igv.js: putting the Integrative Genomics Viewer into a web page
Embeddable genomic visualization component based on the Integrative Genomics Viewer
At a glance
- What is it?
- igv.js is the JavaScript build of the IGV genome browser, packaged as a single file with no external dependencies so that a lab or a paper can show real genomic data inside an existing web application. The interesting engineering is the shadow root, which is how a genome viewer with its own styling and its own DOM ends up living inside a page it does not own.
- Who is it for?
- Adopt igv.js if you need a genome browser inside a page you control, since the whole point is that the viewer comes as one dependency-free file and keeps its own styling out of your stylesheet. Do not adopt it if you need the desktop application instead, because this is the embeddable build and the IGV desktop app is a separate thing.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 8 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One file, no dependencies, and a browser that expects ES6
igv.js is an embeddable interactive genome visualization component developed by the Integrative Genomics Viewer team, and the first line of the installation section sets the tone of the whole project.
igv.js consists of a single javascript file with no external dependencies.
That is a strong constraint for a component that reads CRAM alignment files, decodes variants, renders coverage tracks and draws a genome ideogram, and it is the constraint that makes the library usable in places where a dependency tree is a problem. A genome browser inside a company portal, inside a paper's supplementary site, or inside a lab notebook served from a static host is a use case where a single script tag beats a package manager.
The build output reflects that. There are pre-built files for script include, AMD or CJS module systems in igv.min.js, and an ES6 module in igv.esm.min.js, and both are served from a jsDelivr CDN path. Installing with npm works too, and the guidance is to source the appropriate file for your module system from node_modules/igv/dist.
The browser requirement is stated without hedging. igv.js require a modern web browser with support for Javascript ECMAScript 2015 (ES6), and the browserslist field in the package manifest says greater than 1 percent, not dead. The manifest also declares a devEngines requirement of node 22.13 or newer with onFail set to error, so the build will refuse to run on an old Node rather than fail confusingly.
The licence is MIT, and the project is a peer of the IGV desktop application rather than a fork of it, which matters for how you position it to users.
The API surface: a container div, a config object, and a promise
The usage section is short enough to memorise, and the shape of it is what an embeddable component should look like.
To create an igv.js browser you supply a container div and an initial configuration defining the reference genome, initial tracks and other state, to the function igv.createBrowser(div, config). This function returns a promise for an igv.Browser object which can be used to control the browser.
So the contract is: give it a div, give it a config, get back a promise for a browser handle you can drive afterwards. That is a better interface than a constructor that mutates the page, because the promise tells you when the genome reference and the first tracks have actually loaded, which is the moment you need before you can programmatically zoom or select a locus.
The example shows the whole shape with a single CRAM alignment track:
var igvDiv = document.getElementById("igv-div");
var options =
{
genome: "hg38",
locus: "chr8:127,736,588-127,739,371",
tracks: [
{
"name": "HG00103",
"url": "https://s3.amazonaws.com/1000genomes/data/HG00103/alignment/HG00103.alt_bwamem_GRCh38DH.20150718.GBR.low_coverage.cram",
"indexURL": "https://s3.amazonaws.com/1000genomes/data/HG00103/alignment/HG00103.alt_bwamem_GRCh38DH.20150718.GBR.low_coverage.cram.crai",
"format": "cram"
}
]
};
igv.createBrowser(igvDiv, options)
.then(function (browser) {
console.log("Created IGV browser");
})Three details in that are worth noticing. The genome is given as a reference name, hg38, so the viewer resolves the chromosome sizes itself. The locus is given in a plain string form, chr8:127,736,588-127,739,371, which is the coordinate notation a biologist would type. And the track points at a CRAM file with a separate index URL and an explicit format, so the viewer knows to range-request rather than download the whole alignment.
That last point is what makes a browser usable in a web page at all. A CRAM alignment for one sample from the 1000 Genomes project is large, and the index file is what lets the viewer fetch only the region on screen.
The shadow root, and why the CSS travels inside the JavaScript
The build section explains an architectural decision that is easy to miss and that explains a surprising detail of the distribution.
Additionally the file embedCSS.js is created in the js folder. This contains the CSS required for igv.js, which is injected into a shadow root containing igv.js.
So the stylesheet is compiled into a JavaScript file, and at runtime it is injected into a shadow root. That is a deliberate architecture, and it solves a problem that a genome browser embedded in someone else's page would otherwise have.
The IGV interface is visually dense and specific: ideogram, coordinate ruler, track panes with their own headers, tooltips, popup windows with their own layout. If all of that styling lived in the page's stylesheet, it would either leak into the host application or be overridden by it. A shadow root gives the component its own style scope, so the host page's CSS does not reach in and the viewer's CSS does not leak out.
The cost is that the build has a step most JavaScript projects do not have. The build script in the manifest is a chain: it updates the version, compiles the Sass, generates the embed CSS, runs rollup, and then copies the artefacts. There is a separate script for the IIFE build, which uses a different rollup config, and a watch script for the CSS alone.
The development notes add the detail that catches people out. Development can be done directly from the source files by importing igv.js from js/index.js, and the dist files are not required for development, however you must build at least once to compile the CSS and create the required file js/embedCss.js.
So a fresh clone does not work with a plain import until you have run a build once. That is a small thing, and it is the price of the shadow root approach.
Building it, and the clone that takes too long
The build instructions are short, and the caveat attached to them is the useful part.
git clone https://github.com/igvteam/igv.js.git
cd igv.js
npm install
npm run buildThe note says that igv.js has a large history with many commits which can make cloning and building the entire history time consuming. To clone just the latest commit, use the --depth option, for example:
git clone --depth 1 https://github.com/igvteam/igv.js.gitA large history is a real cost for a component that people want to try in a browser console. The workaround is a one-line flag, and the fact that the documentation bothers to mention it tells you how large the history is.
The platform requirements are stated with a bit of hedging that is worth repeating. Building igv.js and running the examples require Linux or MacOS. Other Unix environments will probably work but have not been tested. Windows users can use the Windows Subsystem for Linux.
So there is no native Windows build path for contributors, which is a reflection of where the maintainers are and of the fact that the project has been developed on Unix for a long time.
The test suite is run with npm run test, and the pretest hook runs the CSS update first, which follows from the shadow root arrangement: the tests need the embedded CSS to exist, and the build step is what produces it. The test runner is mocha with the tdd interface, and the JavaScript engine for the CRAM decoding comes from @gmod/cram.
The rollup configuration is split into two files, rollup.config.js and rollup.config.iife.js, matching the two distribution targets.
What the examples tell you about what the component can do
The examples linked from the README are effectively the feature list, and they are a good indicator of the scope of what an embeddable viewer has to handle.
There is an alignments example, an interactions example, a copy number example, a multiple regions example, a Mutation Annotation Format example, a variant color options example, and a further collection. The URLs reveal the version the examples are pinned to, and they are hosted under the IGV web release tree.
The formats in the examples directory are more revealing still. There are base modification examples, bedpe interact, copy number in two sizes, custom file format, custom reader, custom webservice, custom search service, cytoband names, data URI, dynamic sequence, events, functional URL, GenBank, GFF colors, HiC from 4DN, iframe embedding, and IGV links.
Two of those deserve a note. The custom reader, custom file format and custom webservice examples are about extending the component to read data it does not know about, which is the difference between a viewer you can use and a viewer you can build on. And the iframe example is about embedding, which tells you the project has thought about the case where a shadow root is not enough and the component has to live in its own frame.
The examples also show the scope of the data being displayed: Hi-C contact maps, structural variants in bedpe format, base modifications, copy number, and events alongside alignments. This is not a reference genome browser with a handful of features, it is a general tool for reading genomic data, and the embeddable build carries that scope with it.
The API documentation is separate, at the IGV developer documentation site, and the release notes are on the GitHub releases page.
Editorial conclusion
Adopt igv.js if you need a genome browser inside a page you control, since the whole point is that the viewer comes as one dependency-free file and keeps its own styling out of your stylesheet. Do not adopt it if you need the desktop application instead, because this is the embeddable build and the IGV desktop app is a separate thing. Before you ship it, check that your users are on browsers with ES6 support, and read the release notes at the version you pin, since the releases move quickly and the track format support is where changes land.
Frequently asked questions
How do I install and load igv.js in a web page?
igv.js is a single JavaScript file with no external dependencies. You can import the ES6 module from jsDelivr, include igv.min.js with a script tag which defines an igv global, or install with npm and source the right file from node_modules/igv/dist.
How do I create a genome browser with igv.js?
Supply a container div and a config object with the reference genome, initial locus and tracks to igv.createBrowser(div, config). It returns a promise for an igv.Browser object that you can then use to control the browser.
Does igv.js need any external dependencies at runtime?
No. The documentation states that igv.js consists of a single javascript file with no external dependencies, which is why it can be served from a CDN or dropped into a static page without a package manager.
What are the build and browser requirements for igv.js?
Building requires Linux or MacOS with node.js, and Windows contributors are pointed at the Windows Subsystem for Linux. The component itself requires a modern browser with ECMAScript 2015 support, and the manifest sets a devEngines floor of node 22.13.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/igvteam-igv-js)Was this useful?