Browser engine
The genome browser panel in Genie's project workspace and in read-only shared views is rendered by eg3, the third-generation WashU Epigenome Browser engine. Genie vendors a pre-built copy of eg3 and wraps it in a small adapter. Genie's own native browser packages are still used for the public landing browser, the demo app, developer pages and the IGVF bundle.
Vendored packages
| Folder | Package | Version | Contents |
|---|---|---|---|
vendor/eg3/wuepgg3-track/ | @eg3/tracks (npm name wuepgg3-track) | 61.9.8-genie.5 | The rendering engine: index.es.js with hashed ES chunks, index.umd.js, style.css, hand-written index.d.ts, placeholder images |
vendor/eg3/eg-adapter/ | @eg3/adapter | 0.1.0 | Host-app adapter: region math, feature-interaction normalization, track factories and the <Eg3Browser> mount wrapper (dist/index.js, dist/index.d.ts) |
Both are build outputs, not source. apps/standalone depends on them with file: dependencies. The source lives in the separate eg3 repository (eg-tracks/ and eg-adapter/).
Never edit files in vendor/eg3/ directly. Change the eg3 source, rebuild, and copy the build output in.
Updating the engine
Run from the genie/ root. EG3_ROOT points at your eg3 checkout. The last cp copies the hashed ES chunks. Before pnpm install, bump "version" in vendor/eg3/wuepgg3-track/package.json.
EG3_ROOT=../../eg3
(cd "$EG3_ROOT/eg-tracks" && yarn build:lib)
G=vendor/eg3/wuepgg3-track
rm -f "$G"/*.js
cp "$EG3_ROOT/eg-tracks/dist/index.es.js" \
"$EG3_ROOT/eg-tracks/dist/index.umd.js" \
"$EG3_ROOT/eg-tracks/dist/style.css" "$G"/
cp "$EG3_ROOT"/eg-tracks/dist/*-*.js "$G"/
pnpm install
- Genie consumes the ES build.
index.umd.jsis kept for bundlers that cannot handle the ES chunks. - Remove the old
*.jsfiles before copying. Chunk names are content-hashed, so stale chunks would otherwise pile up and the old entry would keep importing them. index.d.tsis hand-written because eg3 has no declaration build. Update it when the public surface changes.- Keep the placeholder images in
images/;style.cssrefers to them.
Updating the adapter
EG3_ROOT=../../eg3
(cd "$EG3_ROOT/eg-adapter" && node build.mjs)
cp "$EG3_ROOT/eg-adapter/dist/index.js" "$EG3_ROOT/eg-adapter/dist/index.d.ts" \
vendor/eg3/eg-adapter/dist/
The adapter build keeps react and @eg3/tracks external. Its types/index.d.ts is hand-written and copied to dist/index.d.ts by the build.
The same engine is also vendored (UMD build) in the IGVF catalog frontend. Any eg3 change must be re-vendored and version-bumped there too, because yarn v1 caches file: dependencies by version.
The Eg3Browser component
@eg3/adapter exports Eg3Browser and its types.
| Prop | Type | Notes |
|---|---|---|
genomeName | string | eg3 genome id, for example hg38 |
tracks | ITrackModel[] | eg3 track models (see Track mapping) |
viewRegion | string | chr:start-end |
onViewRegionChange | (region: string) => void | Called when the user drags or zooms |
onFeatureHoverChange, onFeatureActivate | callbacks | Normalized feature interactions |
onTrackContextMenu | (event) => boolean | void | Genie uses this to show its own track menu |
onTrackFetchStatus | (event) => void | Per-track fetch status, used by the Track Inspector |
onTracksChange | (tracks) => void | |
highlights, onHighlightsChange | Highlight intervals | |
interactionOptions | Options for feature-interaction normalization | |
legendWidth | number | Genie passes 120 |
heightPx, widthPx | number | null | |
showToolBar, showGenomeNav | boolean | Default false; Genie leaves both off |
darkTheme, className, style | ||
browserRef | Ref<Eg3BrowserHandle> | Imperative handle |
unsupportedGenomeFallback | ReactNode | Rendered when eg3 does not know the genome |
Eg3BrowserHandle has panLeft(), panRight(), zoom(factor, focal?), setViewRegion(region), getViewRegion() and getRootElement().
The adapter mounts eg3's track container with the drag tool fixed, so dragging inside the panel pans. With the toolbar and genome navigator off, there is no ideogram, cytoband or minimap in the workspace panel. When the genome is not supported, Genie shows Genome '<id>' is not supported by the genome browser engine.
The adapter also exports helpers such as parseGenomicRegion, formatGenomicRegion, clampRegionToChromosome, panRegion, zoomRegion, normalizeRegionString, isGenomeSupported, getGenomeChromosomeLengths, getGenomeDefaultRegion, makeEg3UrlTrack, makeEg3TextTrack, makeEg3RulerTrack, makeEg3GeneAnnotationTrack, EG3_SUPPORTED_TRACK_TYPES and isEg3SupportedTrackType.
Region strings
The adapter accepts region strings that match:
^([^\s:]+):([0-9,]+)-([0-9,]+)$
- One chromosome per region:
chr8:127,700,000-127,760,000orchr8:127700000-127760000. Commas are allowed in the numbers. - The end must be greater than the start.
- The adapter's
panLeft(),panRight()andzoom()handle methods, and thepanRegion,zoomRegionandnormalizeRegionStringhelpers, keep a minimum span of 20 bp and clamp the region to the chromosome: a span as long as the chromosome or longer becomes the whole chromosome. Chromosome lengths are looked up with or without thechrprefix.setViewRegion()only parses the string and does not clamp. - Genie's own zoom and pan controls change the region through the native region model (
DisplayedRegionModel), so the adapter's 20 bp floor does not apply to them.
Genie's stored view region can come from the native models, which allow windows that cross chromosomes. Before passing it to eg3, GenomeBrowserPanel replaces a cross-chromosome window with the whole of the chromosome that the window covers most.
Track mapping
apps/standalone/src/app/lib/eg3TrackMapping.ts turns Genie TrackModel objects (as stored in browser-state.json) into eg3 ITrackModel objects.
| Rule | Detail |
|---|---|
| Type | Lower-cased. rgbpeak is aliased to bigbedcolor (same format: bigBed with itemRgb). No other aliases; for example longrangecolor is not mapped onto longrange because the column layouts differ. |
| Unsupported types | toEg3Track returns null; the panel lists them in a notice ("N track(s) not rendered by this engine: …") |
| Name | For gene annotation tracks the eg3 name is the gene set id (geneSet, then config.geneSet, then name, id, or refGene), because eg3 picks the annotation collection from the name. For other tracks: name, then id. |
| Label | options.label = label, then name |
| Height | heightPx becomes options.height. An explicit options.height wins because options are spread afterwards. |
| Genome | genome, then config.genome, then the project genome |
| Metadata | Track metadata plus genieTrackId and genieTrackType, so menu and inspector events can be mapped back to Genie track ids |
| Passed through | url, indexUrl, fileObj, isText, textConfig, filetype, apiConfig, showOnHubLoad, queryEndpoint, querygenome, child tracks (mapped recursively) |
| Not passed | files (Genie types it as an array; eg3 expects one Blob) |
The panel also normalizes gene tracks before mapping (default row limits, GENCODE category colours) and resolves backend-relative URLs, such as peak result files, to absolute URLs.
Supported track types
eg3 accepts 32 track types plus the rgbpeak alias:
ruler, bigwig, bigbed, bigbedcolor, geneannotation, genomealign, refbed, bed, bedcolor, bedgraph, dbedgraph, repeatmasker, rmskv2, vcf, omeroidr, bam, snp, modbed, categorical, jaspar, methylc, dynseq, boxplot, qbed, hic, biginteract, longrange, matplot, dynamic, dynamichic, dynamiclongrange, dynamicbed.
These eg-react types are not rendered in the workspace: cool, longrangecolor, hammock, g3d, pairwise, snv, snv2, protein, omero4dn, bigchain, brgfa, ballc, graph. The Remote Tracks dialog offers the 31 types that are both in the eg-react list and supported by eg3. See Track types.
Image export
File → Export Image calls exportEg3BrowserImage in apps/standalone/src/app/lib/eg3ImageExport.ts:
- Takes the eg3 root element from the browser handle and measures the rendered track stack (not the stretched panel), so the image has no empty space below the tracks.
- Waits for web fonts and two animation frames so the latest drawing is on screen.
- Rasterizes the element with
html-to-image(toBlob) on a white background at pixel ratio 2. - Lowers the pixel ratio if needed so that no side exceeds 16,384 px and the area stays under 64 megapixels.
The file is saved as genie-<genomeId>-<locus>.png (characters unsafe in file names are replaced) and a "Genome browser image exported" toast appears. There is no SVG export. The native GenomeBrowser has its own exportImage() with the same background, pixel ratio and caps.
Licence obligations
Genie's browser panel uses the WashU Epigenome Browser engine (eg3), which is free for non-commercial use under its own licence. eg3 is not covered by any Genie licence (the Genie repository has no licence file yet).
The eg3 licence agreement grants a non-exclusive, royalty-free licence to use, copy, modify, merge, publish and distribute the software, excluding commercial use or sales. It also requires that:
-
The licence agreement and its copyright notice are included in all copies or substantial portions of the software. The notice is:
Copyright (c) 2018 Washington University in St. Louis -
Written publications concerning the use of the software include the citation that the licence specifies.
The vendored copy in vendor/eg3/ does not currently include the eg3 licence text. Add the licence agreement and notice to vendor/eg3/ before distributing any build, and keep it with every copy of the engine, including the desktop app and any other project that vendors the engine.
Native browser packages
The native stack is @genie/genome-browser with @genie/genome-track-container and @genie/genome-tracks-standard (see Monorepo layout). It is still used in these places:
| Where | What renders |
|---|---|
Public landing browser (/ and /browser/:genomeId in builds with backend mode static) | StandardTrackContainer; hg38 and hg19 only, with a "Region" box, "Go", "Pan Left", "Pan Right", "Zoom In" and "Zoom Out" |
Developer pages (/dev/genome-track, /dev/genome-track/hg19, /dev/genome-track/hg38) | Native track container and viewport |
apps/genome-track-demo | GenomeBrowser with registerStandardTracks |
| IGVF bundle | GenomeBrowser, TrackRegistry, registerStandardTracks, StandardTrackContainer, DisplayedRegionModel, EG_REACT_TRACK_TYPES and hg38 helpers |
Building the IGVF bundle
pnpm bundle:igvf-genome --outdir <output folder>
The script (scripts/build-igvf-genome-bundle.mjs) bundles scripts/igvf-genome-bundle.entry.ts with esbuild as an ES module and writes index.js, index.css and index.d.ts (copied from scripts/igvf-genome-bundle.d.ts). react, react-dom and react/jsx-runtime stay external. The output folder (or the folder given with --clean-root) is deleted before the build, so point it at a dedicated folder.
The native packages register 45 track type names, more than eg3 renders. Those registrations apply only where the native stack is used.