Skip to main content

Consolidated docs

This document is a collection of all our documentation. It includes our quick start guides, user guides, configuration guides, CLI guides, developer guides, and FAQ.

Note

You can browse the other documents individually using the sidebar on the left. This page is to help simplify ctrl+f searching and easy browsing.

You can also download a pdf version of these same docs located at https://jbrowse.org/jb2/jbrowse2.pdf.

JBrowse desktop quick start

In this guide, we'll get the JBrowse desktop application running on your computer.

Installing JBrowse desktop

Installing on Windows

Click here to download the latest Windows installer executable.

Double-click the downloaded installer and it will install and open JBrowse. You can now open JBrowse like any other program.

Installing on MacOS

Click here to download the latest MacOS release artifact.

When the .dmg file is downloaded, double click, and drag JBrowse 2 into 'applications'.

You can now open JBrowse 2 like any other application on your Mac.

Installing on Linux

Click here to download the latest Linux AppImage release.

Start it in one of two ways:

In the terminal

Using the AppImage file on linux, all that is needed is to make the file executable which you can do in a terminal

## Make the AppImage file executable, only need to do this once
chmod a+x jbrowse-desktop-*-linux.AppImage
## Run!
./jbrowse-desktop-*-linux.AppImage
In your file explorer

This may vary slightly depending on your distribution but should basically follow these steps:

  1. Right-click on the AppImage file and select "Properties"
  2. Go to the "Permissions" tab
  3. Check "Allow executing file as program" and close

You can now double-click the AppImage file to launch JBrowse.

JBrowse Desktop start screen

After you have installed and started JBrowse Desktop you will see a start screen like this:

Screenshot showing the start screen on JBrowse desktop
Figure: Screenshot showing the start screen on JBrowse desktop

On the left hand panel, "Launch new session" can launch a new session using either your own custom genome (which you can load using an indexed FASTA or a twobit file via open sequence file) or a pre-loaded genome via the "Quickstart list".

On the right hand panel is the "Recently opened sessions". This includes sessions that you have explicitly saved, and sessions that were autosaved (i.e. ones that you didn't explicitly use "Save as" on). You can re-open your sessions by clicking on the session name.

Special features on the start screen

Converting a saved session into a quickstart entry

If you study a rare species, you might find it useful to customize your quickstart panel. You can convert a session in the "Recently opened sessions" into an entry that appears in the quickstart list.

To do this: Click a checkbox next to a session in the "Recently opened sessions" table, and then hit the

icon next to the trash can icon. This is helpful if you want to make your own custom organism a template for quickstarts in the future.

Selecting multiple entries from the quickstart panel

Users can also hit the checkbox for multiple species in the quickstart list, and then the sessions are combined which can be helpful for comparative genomics.

Next steps

Check out the user guide for more info on how to use JBrowse Desktop. This covers all the features that are available with screenshots and instructions.

JBrowse web quick start

In this guide, we'll get an instance of JBrowse web running on your computer's browser.

Are you an administrator, or want to install via CLI to get access to configuration tools? Follow our CLI quick start.

Want JBrowse desktop? Follow our JBrowse desktop quick start.

Downloading manually

Download JBrowse 2 manually here.

Once you have downloaded the ZIP file, extract it to the directory where you would like to have JBrowse 2.

Checking the download

The directory where you downloaded JBrowse should look something like this:

jbrowse2/
├── asset-manifest.json
├── favicon.ico
├── index.html
├── manifest.json
├── robots.txt
├── static/
├── test_data/
└── version.txt

Running JBrowse 2

JBrowse 2 requires a web server to run. It won't work if you try to directly open the index.html in your web browser. We can use a simple server to check that JBrowse 2 has been downloaded properly. Run

cd jbrowse2/
npx serve . # use npx serve -S . if you want to refer to symlinked data later on

which will start a web server in our JBrowse 2 directory.

Navigate to the location specified in the CLI's output (likely http://localhost:3000).

Your page should look something like this:

JBrowse 2 screen showing no configuration found
Figure: JBrowse 2 screen showing no configuration found

Click on the sample config to see JBrowse 2 running with a demo configuration. It should look like this:

JBrowse 2 screen with a sample configuration
Figure: JBrowse 2 screen with a sample configuration

Congratulations! You're running JBrowse 2.

Next steps

Now that JBrowse 2 is set up, you can configure it with your own genomes and tracks. There are two ways you can configure JBrowse 2: with the JBrowse CLI (guide here) or with JBrowse 2's built-in graphical configuration editing (guide here).

JBrowse web quick start via CLI

In this guide, we'll get an instance of JBrowse web running on your computer's browser.

Just want to download JBrowse web and get started? Follow our JBrowse web quick start.

Want JBrowse desktop? Follow our JBrowse desktop quick start.

Prerequisites

  • Ability to run commands on the command line
  • A stable and recent version of node
caution

If you are using apt as your package manager, we recommend not using it to install Node.js. Good alternatives include NodeSource or NVM.

Downloading JBrowse 2 using the JBrowse CLI

The JBrowse CLI can help perform many tasks to help you manage JBrowse 2, such as:

  • create a new instance of JBrowse 2 automatically
  • update an existing instance of JBrowse 2 with the latest released version
  • configure your JBrowse 2 instance

Installing the CLI tools

To globally install the JBrowse CLI, run

npm install -g @jbrowse/cli

After running this command you can then test the installation with

jbrowse --version

which will output the current version of the JBrowse CLI.

note

If you can't or don't want to globally install the JBrowse CLI, you can also use the npx command, which is included with Node.js, to run JBrowse CLI without installing it. Simply replace jbrowse with npx @jbrowse/cli in any command, e.g.

npx @jbrowse/cli --version

Using jbrowse create to download JBrowse 2

In the directory where you would like to download JBrowse 2, run

jbrowse create jbrowse2

Checking the download

The directory where you downloaded JBrowse should look something like this:

jbrowse2/
├── asset-manifest.json
├── favicon.ico
├── index.html
├── manifest.json
├── robots.txt
├── static/
├── test_data/
└── version.txt

Running JBrowse 2

JBrowse 2 requires a web server to run. It won't work if you try to directly open the index.html in your web browser. We can use a simple server to check that JBrowse 2 has been downloaded properly. Run

cd jbrowse2/
npx serve . # use npx serve -S . if you want to refer to symlinked data later on

which will start a web server in our JBrowse 2 directory.

Navigate to the location specified in the CLI's output (likely http://localhost:3000).

Your page should look something like this:

JBrowse 2 screen showing no configuration found
Figure: JBrowse 2 screen showing no configuration found

Click on the sample config to see JBrowse 2 running with a demo configuration. It should look like this:

JBrowse 2 screen with a sample configuration
Figure: JBrowse 2 screen with a sample configuration

Congratulations! You're running JBrowse 2.

Next steps

Now that JBrowse 2 is set up, you can configure it with your own genomes and tracks. There are two ways you can configure JBrowse 2: with the JBrowse CLI (tutorial here) or with JBrowse 2's built-in graphical configuration editing (guide here).

User guide

This user guide is a comprehensive compilation of all general UI navigation, tools/features available for some of the different track types, and other useful features for using JBrowse.

Use the navigation menu on the right to skip to a topic of interest, if applicable.

Linear genome view usage

To open a linear genome view (LGV), use the menu bar: ADD -> Linear genome view

Scrolling

You can scroll side to side using your mouse wheel or via click and drag. Left and right pan buttons found in the header of the LGV can also be used to scroll in their respective directions.

Zooming

The zoom buttons and the slider bar found in the header of the linear genome view can be used to zoom in and out on the view

You can also hold the Ctrl key and use your mousewheel or trackpad to scroll to zoom in and out.

Re-ordering tracks

Click and drag up or down on the drag handle on the track labels (indicated by six vertical dots) to reorder tracks.

(1) Use Add, Linear genome view to add a new LGV. (2) The pan buttons can be used to scroll left or right. (3) The zoom buttons or the slider can be used to zoom on the view. (4) Tracks can be reordered by clicking and dragging the drag handle indicated by six vertical dots.
Figure: (1) Use Add, Linear genome view to add a new LGV. (2) The pan buttons can be used to scroll left or right. (3) The zoom buttons or the slider can be used to zoom on the view. (4) Tracks can be reordered by clicking and dragging the drag handle indicated by six vertical dots.

The location search box is located at the top of the LGV.

You can search a location in several ways when typing in the search box:

  1. Searching by region and location, e.g. chr1:1..100 or chr1:1-100 or chr1 1 100
  2. Searching by assembly, region, and location, e.g. {hg19}chr1:1-100
  3. Searching discontinuous regions, delimited by a space, and opening them side-by-side, e.g. chr1:1..100 chr2:1..100
  4. Searching in any of the above ways and appending [rev] to the end of the region will horizontally flip it, e.g. chr1:1-100\[rev\]
  5. If configured, searching by gene name or feature keywords, e.g. BRCA1

To configure name searching, you or the admin of the instance will need to create a "text index". See the configuration guide for more information.

When configured, you can search for gene names or other features via the location search box.
Figure: When configured, you can search for gene names or other features via the location search box.

Opening tracks

To open a new track or connection, use the menu bar: File -> Open track..

After opening the menu item for 'Open track..' a drawer widget for the 'Add a track' form will appear
Figure: After opening the menu item for 'Open track..' a drawer widget for the 'Add a track' form will appear
Tip

There is a circular plus (+) icon button inside the "Available tracks" widget that can also be used to access the "Add a track" form.

(1) Open the 'Available tracks' widget with the button on the far left of the linear genome view. (2) The orange plus (+) icon button in the bottom right the 'Available Tracks' widget can also be used to launch the 'Add a track' form.
Figure: (1) Open the 'Available tracks' widget with the button on the far left of the linear genome view. (2) The orange plus (+) icon button in the bottom right the 'Available Tracks' widget can also be used to launch the 'Add a track' form.

In the "Add a track" form, you can provide a URL to a file to load, or you can also open files from your local machine. In some cases, you need to provide an index (bigwig files for example have no index, but BAM/CRAM or tabix filetypes like VCF/GFF/BED tabix do). In some cases we can automatically infer the index e.g. if you provide a URL for a BAM and the index filename is bamfilename +'.bai' but you may need to manually supply it in some cases (index inference can't be done with files from your local machine)

The following file formats are supported in core JBrowse 2:

  • CRAM
  • BAM
  • htsget
  • VCF (Tabix-indexed)
  • GFF3 (Tabix-indexed)
  • BED (Tabix-indexed)
  • BigBed
  • BigWig
  • JBrowse 1 nested containment lists (NCLists)
  • plain text VCF, BED, CSV, TSV, BEDPE, STAR-fusion output (tabular formats)
  • PAF (synteny/dotplot)
  • Indexed FASTA/BGZip indexed FASTA
  • 2bit
  • .hic (Hi-C contact matrix visualization)

Additional data formats can be supported via plugins; checkout the plugin store.

For tabix files, TBI or CSI indexes are allowed. CSI or BAI is allowed for BAM. Only CRAI is allowed for CRAM. The index will be inferred for BAI or TBI files as filename+'.bai' for example, but if it is different than this, make sure to specify the index file explicitly.

Note

If you are an administrator, you can add tracks with the command line or with the admin server.

Undo and redo

You can undo the closing of a view, track, or any other action in the UI with the Tools->Undo/Redo buttons. The keyboard shortcut "ctrl+z"/"cmd+z"(mac) work for undo as well as "ctrl+y"/"cmd+shift"z"(mac)

Sharing sessions

On JBrowse Web, the main menu bar has a "Share" button to enable users to share their sessions with other people. The share button generates a URL that can be sent to other users.

You cannot copy the URL in your address bar and send it to other users, you must use the "Share" button to share your session.

Note

Sharing sessions is not available for JBrowse Desktop.

The session share dialog, which gives you a short URL to share your session with other users. It is important to use the URLs generated here, rather than copying and pasting your browser's URL to other users.
Figure: The session share dialog, which gives you a short URL to share your session with other users. It is important to use the URLs generated here, rather than copying and pasting your browser's URL to other users.

The session URL will contain the following:

  • what views are on the screen, and settings for the views (e.g. track labels overlapping or offset)
  • what tracks are in the view
  • extra tracks that you added with the "Add track workflow"
  • for the alignments track, the show soft clipping and sort settings on the pileup
  • ...and more!

This means you can share links with your custom tracks with other users, without being a JBrowse admin!

Track menu

Users can access track-specific functions by using the track menu, which is accessible from the track selecter itself ("..." icon) or on the track label (vertical "..."). Some functions are only available when the track is open e.g. from the track label, but more basic options like "About track" are available from the track menu on the track selector.

Screenshot showing how to open the track menu (both in the track selector area and in the track label area of the linear genome view), and an example of a VCF track with it's track menu open
Figure: Screenshot showing how to open the track menu (both in the track selector area and in the track label area of the linear genome view), and an example of a VCF track with it's track menu open

About track dialog

Using the track menu as described above, you can access the "About track" dialog.

Screenshot of the 'About track' dialog for a CRAM file, showing the full CRAM file header and config info. Having the full header of a BAM/CRAM file available is helpful to easily check what genome it was aligned to, for example.
Figure: Screenshot of the 'About track' dialog for a CRAM file, showing the full CRAM file header and config info. Having the full header of a BAM/CRAM file available is helpful to easily check what genome it was aligned to, for example.

Editing track configs

As a non-admin user, in order to edit a track config, you have to make a copy of the track. This will copy it to your "session tracks", which you can edit freely.

Screenshot showing the procedure to copy the track before being able to edit the settings
Figure: Screenshot showing the procedure to copy the track before being able to edit the settings
Rubberband selection

The scale bars accept a click-and-drag action to select a region. Rubberband selection can be performed on both the main (lower) and overview (upper) scale bars.

Screenshot of rubberbanding both the main and overview scalebars. The main scalebar produces extra options on selection, e.g. Zoom to region, Get sequence, etc..
Figure: Screenshot of rubberbanding both the main and overview scalebars. The main scalebar produces extra options on selection, e.g. Zoom to region, Get sequence, etc..
Track label positioning

Track labels can be positioned on their own row or overlapping the data to save vertical screen space. They can also be hidden. This is done by clicking on the hamburger menu for a specific view.

Example of using the overlap and offset track label positioning options.
Figure: Example of using the overlap and offset track label positioning options.
Horizontally flip

The view can be horizontally flipped, or reverse complemented, to make the coordinates go from right to left instead of left to right.

We use triangles pointing in the direction of the orientation in the overview bar to help indicate whether the app is horizontally flipped or not.

Here is an example of before and after horizontally flipping the view:

Before and after horizontally flipping.
Figure: Before and after horizontally flipping.

Sequence track

The sequence track shows the reference sequence and a three-frame translation. If the view is horizontally flipped, the sequence is "reverse complemented" so the bottom three translation frames go to the top, and the top frames go to the bottom.

The sequence track, with a positive strand gene for context, shows the start codon on the first exon in the top-three rows of the translation frame. The bottom panel shows the same view but with the view horizontally flipped, and the gene is now shown reversed and the start codon is in the bottom translation frames.
Figure: The sequence track, with a positive strand gene for context, shows the start codon on the first exon in the top-three rows of the translation frame. The bottom panel shows the same view but with the view horizontally flipped, and the gene is now shown reversed and the start codon is in the bottom translation frames.

Alignments tracks

Visualizing alignments is an important aspect of genome browsers. This guide will go over the main features of the "Alignments track."

The alignments track is a combination of a pileup and a coverage visualization.

Pileup visualization

The pileup is the lower part of the alignments track and shows each of the reads as boxes positioned on the genome.

By default the reads are colored red if they aligned to the forward strand of the reference genome, or blue if they aligned to the reverse strand.

Coverage visualization

The coverage visualization shows the depth-of-coverage of the reads at each position on the genome, and also draws using colored boxes any occurrence of mismatches between the read and the reference genome, so if 50% of the reads had a T instead of the reference A, half the height of the coverage histogram would contain a 'red' box.

Screenshot showing the alignments track, which contains both a coverage view at the top and a pileup view at the bottom
Figure: Screenshot showing the alignments track, which contains both a coverage view at the top and a pileup view at the bottom

Show soft clipping

If a read contains bases that do not map the the genome properly, they can either be removed from the alignment (hard clipping) or can be included, and not shown by default (soft clipping).

JBrowse 2 also contains an option to "show the soft clipping" that has occurred. This can be valuable to show the signal around a region that contains structural variation or difficult mappability.

The soft clipping option is a toggle in the 'Pileup settings' menu.
Figure: The soft clipping option is a toggle in the 'Pileup settings' menu.
Shows what turning on soft-clipping enables for a simulated long-read dataset. There is a simulated structural variant, a deletion, at this position, so the read has bases that map to the other side of the deletion being revealed by this.
Figure: Shows what turning on soft-clipping enables for a simulated long-read dataset. There is a simulated structural variant, a deletion, at this position, so the read has bases that map to the other side of the deletion being revealed by this.

Sort by options

The alignments tracks can also be configured to "sort by" a specific attribute for reads that span the center line.

By default the center line is not shown, but by showing it (detailed below) then you will obtain a better idea of what the "sort by" option is doing.

Showing the center line

  1. Open the hamburger menu in the top left of the linear genome view
  2. Select "Show center line"
The 'show center line' option is a toggle in the LGV menu.
Figure: The 'show center line' option is a toggle in the LGV menu.
The center line is an indicator that shows what base pair underlies the center of the view.
Figure: The center line is an indicator that shows what base pair underlies the center of the view.
Note

The center line is used by the 'Sort by' function discussed in this section; the sort is performed using properties of the feature, or even exact base pair underlying the center line.

Sorting by base pair

Sorting by base pair will re-arrange the pileup so that the reads that have a specific base pair mutation at the position crossing the center line (which is 1bp wide) will be arranged in a sorted manner. To enable Sort by base pair:

  1. Open the track menu for the specific track using the vertical '...' in the track label
  2. Select Pileup settings->Sort by->Base pair
Illustrating the pileup re-ordering that happens when turning on the 'Sort by'->'Base pair'. The sorting is done by specifically what letter of each read underlies the current center line position (the center line is 1bp wide, so sorted by that exact letter)
Figure: Illustrating the pileup re-ordering that happens when turning on the 'Sort by'->'Base pair'. The sorting is done by specifically what letter of each read underlies the current center line position (the center line is 1bp wide, so sorted by that exact letter)

Sort, color and filter by tag

With these features, we can create expressive views of alignments tracks. For example, in the below step-by-step guide, it shows how to color and sort the reads by the HP tag:

Step-by-step guide showing how to sort and color by haplotype with the HP tag.
Figure: Step-by-step guide showing how to sort and color by haplotype with the HP tag.

Color by modifications/methylation

If you have data that marks DNA/RNA modifications using the MM tag in BAM/CRAM format, then the alignments track can use these merks to color these modification. It uses two modes:

  1. Modifications mode - draws the modifications as they are
  2. Methylation mode - draws both unmodified and modifified CpGs (unmodified positions are not indicated by the MM tag and this mode considers the sequence context)
The track menu can be used to access the settings to color by modifications or methylation.
Figure: The track menu can be used to access the settings to color by modifications or methylation.
Screenshot showing the same track in both modifications mode and methylation mode.
Figure: Screenshot showing the same track in both modifications mode and methylation mode.
After the setting has been enabled you can revisit the dialog box to see the current coloring settings.
Figure: After the setting has been enabled you can revisit the dialog box to see the current coloring settings.

Color by orientation

JBrowse uses the same color scheme as IGV for coloring by pair orientation. These pair orientations can be used to reveal complex patterns of structural variation.

See IGV's Interpreting Color by Pair Orientation guide for further details on interpreting these pair orientations.

This shows an inverted duplication, the tandem duplication can produce green arrows which have reads pointing in opposite directions e.g. <-- and -->, while blue arrows which can indicate an inversion point in the same direction e.g. --> and -->.
Figure: This shows an inverted duplication, the tandem duplication can produce green arrows which have reads pointing in opposite directions e.g. <-- and -->, while blue arrows which can indicate an inversion point in the same direction e.g. --> and -->.

Sashimi-style arcs

The alignments track will draw sashimi-track style arcs across spliced alignments (indicated by N in the CIGAR string). If the reads additionally are tagged with XS tags, it will try to draw the arcs using the strand indicated by the alignment.

Sashimi-style arcs that are automatically drawn from spliced alignments. These arcs will be drawn by default on both short-reads e.g. RNA-seq and long reads e.g. Iso-Seq.
Figure: Sashimi-style arcs that are automatically drawn from spliced alignments. These arcs will be drawn by default on both short-reads e.g. RNA-seq and long reads e.g. Iso-Seq.
Note

You can disable these by clicking on the track menu (vertical "..." next to track label, then hovering over SNPCoverage options, and unchecking "Draw arcs").

Insertion and clipping indicators

The alignments track will also draw an upside-down histogram of insertion and soft/hard clipped read counts at all positions, and mark significant positions (covering 30% of the reads) with a colored triangle.

Clipping and insertion indicators are drawn at the top of the alignments track. Purple indicates insertions, the blue indicates soft clipping, and red indicates hard clipping.
Figure: Clipping and insertion indicators are drawn at the top of the alignments track. Purple indicates insertions, the blue indicates soft clipping, and red indicates hard clipping.

Also, insertions that are larger than 10bp are marked with a larger purple rectangle, seen in the screenshot below. Generally, long reads span larger insertions better, so this feature is more prominant with large reads.

Large insertion indicator drawn from long reads, along with the 'show soft clipping' setting turned on for a short read track.
Figure: Large insertion indicator drawn from long reads, along with the 'show soft clipping' setting turned on for a short read track.
Note

You can disable these by clicking on the track menu (vertical "..." next to track label, then hovering over SNPCoverage options, and unchecking "Draw insertion/clipping indicators" and "Draw insertion/clipping counts").

Quantitative tracks

Visualizing genome signals, whether it is read depth-of-coverage or other signal, can often be done by using BigWig or other quantitative feature files.

A simple wiggle track with the XY plot renderer.
Figure: A simple wiggle track with the XY plot renderer.

Viewing whole-genome coverage for profiling CNV

You can refine the resolution of BigWig tracks, and view whole genome coverage to get detailed global views of CNV, for example from whole-genome coverage profiling.

Here is a short picture guide to setup a whole-genome view of a BigWig for CNV coverage visualization:

  1. Open your BigWig track
  2. Go to the view menu and select "Show all assembly regions"
  3. Adjust the "Autoscale type" to your liking, the new options for "Local +/- 3sd" allows the autoscaling to avoid outliers
  4. Go to the track menu and select "Turn off histogram fill", which then shows only a dot for each point on the graph
  5. Go to the track menu and select "Resolution->Finer resolution" a couple times until resolution looks nice
Note

All tracks have a drag handle on the bottom, which you can drag down to make the track taller.

A step-by-step guide to view a whole-genome CNV profile of coverage from a BigWig file.
Figure: A step-by-step guide to view a whole-genome CNV profile of coverage from a BigWig file.

Multi-quantitative tracks

In 2.1.0, we created the ability to have "Multi-quantitative tracks" which is a single track composed of multiple quantitative signals, which have their Y-scalebar synchronized. There are 5 rendering modes for the multi-quantitative tracks.

  • xyplot
  • multirowxyplot
  • multiline
  • multirowline
  • multidensity

You can interactively change these settings through the track menu.

Track menu for the multi-quantitative tracks showing different renderer types.
Figure: Track menu for the multi-quantitative tracks showing different renderer types.

With the "multi-row" settings (multirowxyplot, multirowline, multidensity) the track colors are not modified. For the overlapping (xyplot, multiline), the tracks will be autoassigned a color from the palette. You can manually customize the subtrack colors from the track menu as well.

The color/arrangement editor for multi-quantitative tracks let's you change individual subtrack colors, or their ordering in the row based layouts.
Figure: The color/arrangement editor for multi-quantitative tracks let's you change individual subtrack colors, or their ordering in the row based layouts.

Oftentimes, one of the outliers on one of the subtracks may affect the Y-scalebar too much, so it is often helpful to use the "Autoscale type->Local +/- 3SD" setting (3 standard deviations are displayed). Manually configuring the min or max scores is available via the track menu also.

Adding multi-quantitative tracks via the UI

There are several ways to create multi-quantitative tracks from scratch.

  1. Using the add track panel to open up a list of URLs for bigwig files, or from several local tracks from your machine
  2. Using the track selector to add multiple tracks to your current selection, and then creating a multi-wiggle track from the tracks in your selection
  3. Hardcoding the multiwiggle track in your config file (see multi-quantitative track configuration for more info)
Using the add track widget, you can use the select dropdown to access alternative 'add track workflows' including the multi-wiggle add track workflow. In the multiwiggle add track workflow, you can paste a list of bigWig file URLs, or open up multiple bigwig files from your computer.
Figure: Using the add track widget, you can use the select dropdown to access alternative 'add track workflows' including the multi-wiggle add track workflow. In the multiwiggle add track workflow, you can paste a list of bigWig file URLs, or open up multiple bigwig files from your computer.
Using the track selector, you can add multiple tracks to your current selection. You can use the '...' dropdown menu to add a single track or a whole category of tracks to your selection. Then, the 'shopping cart' icon in the header of the add track widget let's you create a multi-wiggle track from your selection.
Figure: Using the track selector, you can add multiple tracks to your current selection. You can use the '...' dropdown menu to add a single track or a whole category of tracks to your selection. Then, the 'shopping cart' icon in the header of the add track widget let's you create a multi-wiggle track from your selection.

Variant tracks

Visualizing variant tracks from the VCF format alongside the original alignment evidence track is a common workflow for validating your results, shown below:

Variant track indicating a SNP alongside the alignment track evidence.
Figure: Variant track indicating a SNP alongside the alignment track evidence.

Variant widget

The variant features have a specialized widget that contains a table indicating all the calls that were made in a multi-sample VCF. Some VCF files, like the 1000 genomes VCF, can contain thousands of samples in a single file. This table can display the details.

Screenshot showing the variant feature sidebar with a filtered by genotype (with alternative allele '1'). Users can also filter by sample name or other attributes.
Figure: Screenshot showing the variant feature sidebar with a filtered by genotype (with alternative allele '1'). Users can also filter by sample name or other attributes.

Comparative views

The dotplot view is a 2D comparative view that can display alignments between different genome assemblies, or even compare a long-read or NGS short-read against the genome.

Opening a dotplot view or synteny view

  1. Navigate on the header bar Add->Dotplot view or Add->Linear synteny view
  2. Select the genome assemblies of interest
  3. Optionally, add a .paf, .out (MashMap), .delta (Mummer), .chain, .anchors or .anchors.simple (MCScan) file
Adding a new dotplot or synteny view via the menubar.
Figure: Adding a new dotplot or synteny view via the menubar.
Screenshot of the import form for a dotplot or synteny view. You can select two different assemblies and an additional file can be supplied.
Figure: Screenshot of the import form for a dotplot or synteny view. You can select two different assemblies and an additional file can be supplied.
Screenshot of a dotplot visualization of the grape vs the peach genome.
Figure: Screenshot of a dotplot visualization of the grape vs the peach genome.
Screenshot showing the linear synteny view for the grape vs peach genome.
Figure: Screenshot showing the linear synteny view for the grape vs peach genome.

Opening a synteny view from a dotplot view

You can open a synteny view from a dotplot view by selecting a region on the dotplot and clicking "Open linear synteny view", shown below:

Screenshow showing the 'click and drag' selection over the dotplot view which prompts you to open up a linear synteny view from the selected region.
Figure: Screenshow showing the 'click and drag' selection over the dotplot view which prompts you to open up a linear synteny view from the selected region.

Long read vs reference plots

You can also launch a dotplot view that compares a long read to the reference genome:

  1. With your alignments track open, right click on an alignment
  2. Select "Dotplot read vs ref" or "Linear read vs ref" in the context menu
Screenshot of a dotplot produced by a long read vs the reference genome.
Figure: Screenshot of a dotplot produced by a long read vs the reference genome.
Screenshot of a 'synteny' view produced by a long read vs the reference genome.
Figure: Screenshot of a 'synteny' view produced by a long read vs the reference genome.

Hi-C tracks

Visualizing Hi-C data can be performed with .hic files generated by the Juicebox software suite. It uses the hic-straw module developed by the juicebox/igv.js team to visualize it in JBrowse.

Currently configuration options are basic for Hi-C tracks, see the comprehensive config guide for info about configuring Hi-C tracks.

Screenshot of a Hi-C track.
Figure: Screenshot of a Hi-C track.

SV inspector

The Structural Variant (SV) inspector is a "workflow" that is designed to help users inspect structural variant calls.

Opening the SV inspector

We can start the SV inspector by launching it from the App level menu bar

The SV inspector can be launched from the main menu bar.
Figure: The SV inspector can be launched from the main menu bar.

This will bring up an "import form" that asks you for your SV evidence.

The following formats are supported:

  • CSV, TSV
  • VCF or VCF.gz (plain text VCF, or (b)gzipped VCF)
  • BED, BEDPE
  • STAR-fusion result file
The import form for getting started with the SV inspector.
Figure: The import form for getting started with the SV inspector.

Example SV inspector workflow

We can start the SV inspector workflow by opening up this file containing translocation events called from a breast cancer cell line SKBR3, based on these published data.

## Example VCF for use in the SV inspector
https://jbrowse.org/genomes/hg19/skbr3/reads_lr_skbr3.fa_ngmlr-0.2.3_mapped.bam.sniffles1kb_auto_l8_s5_noalt.new.vcf

Copy this URL and paste it into the import form and select hg19:

The SV inspector with the import form and URL pasted.
Figure: The SV inspector with the import form and URL pasted.

SV inspector results

After loading the user's requested file, you will have a tabular view with each row representing a row of the file you opened, along with a whole-genome overview of the SVs on the right

The SV inspector with loaded results.
Figure: The SV inspector with loaded results.

Now here is where things can become interesting

We can search and filter the table, with filtering and searching being reflected in the circular view as well.

The SV inspector with filter applied.
Figure: The SV inspector with filter applied.

Launching breakpoint split view

By clicking on the features in the circular view, or clicking on the triangle drop-down on the leftmost column of the table, we can dynamically launch a new view of the data that is called the "split view" or the "breakpoint split view"

This allows us to inspect the breakpoints of the structural variant, and compare each side to the alignments.

Screenshot of the 'breakpoint split view' which examines the breakpoints of a structural variant, e.g. an interchromosomal translocation, and connects supporting reads (black splines) and the variant call itself (green thicker line, with feet indicating directionality).
Figure: Screenshot of the 'breakpoint split view' which examines the breakpoints of a structural variant, e.g. an interchromosomal translocation, and connects supporting reads (black splines) and the variant call itself (green thicker line, with feet indicating directionality).

Getting the protein sequence for features

If you have a track with gene or transcript level features, then the feature detail sidebar will automatically stitch together the sequence for that feature. Options include:

  • CDS - the coding sequences, spliced together
  • Protein - performs protein translation on the CDS, currently assuming the default codon translation table
  • cDNA - the CDS plus UTR, or just all exons if a non-coding gene
  • Gene w/ introns - the entire gene region sequence with the introns included
  • Gene w/ 10bp of introns - the spliced gene sequence with 10bp around the splice sites shown
  • Gene w/ 500 up+down stream - the entire gene region with 500bp upstream and downstream (shown in light red)
  • Gene w/ 500 up+down stream + 10bp of introns - the spliced gene sequence with 10bp around the splice sites shown and the up/down stream shown

Some of the parameters such as 500bp and 10bp are arbitrarily chosen, if you are interested in adjusting these default parameters let us know.

The sequence for the upstream and downstream, exons, and intron sequences shown in the feature details.
Figure: The sequence for the upstream and downstream, exons, and intron sequences shown in the feature details.

Using the plugin store

Users can add plugins to their session using the in-app plugin store. The plugin will be added to your "session" which can be shared with the share button (or if you are an admin running the admin-server, then it will be added to the config file).

This can add extra functions, tracks, or many other interesting features. For example, if you add the CIVIC plugin, it will automatically add a track that contains the CIVIC cancer gene annotations to hg19.

Note

Not all plugins are directly useful from being added, and require hand-editing of the configuration file to be useful. If you would like to use such a plugin and do not have access to the configuration file, contact your administrator.

Screenshot showing the plugin store inside the app.
Figure: Screenshot showing the plugin store inside the app.

Using the bookmark widget

The "bookmark widget" can store lists of interesting regions that you might like to easily revisit.

Clicking and dragging on a region can be used to create a bookmark.
Figure: Clicking and dragging on a region can be used to create a bookmark.

The bookmark stores a list of single regions (chromosome, start, and end coordinate), and clicking on the regions in the bookmark widget will launch a linear genome view at that region.

You can also import a list of regions from a BED file.

Importing a list of regions from a BED file.
Figure: Importing a list of regions from a BED file.
Note

You can add "notes" for your list of regions by double clicking on the label field to easily "annotate" your datasets.

Screenshot editing description.
Figure: Screenshot editing description.

Finally, you can export your list of regions to a BED file or TSV.

Config guide

The following guide provides comprehensive information regarding the anatomy and usage of the config.json file that is critical for running a JBrowse 2 session.

info

To learn how to configure JBrowse with assemblies and tracks using the CLI or the GUI checkout those respective tutorials.

Intro to the config.json

A JBrowse 2 configuration file, a config.json, is structured as follows

{
"configuration": {
/* global configs here */
},
"assemblies": [
/* list of assembly configurations, e.g. the genomes being viewed */
],
"tracks": [
/* array of tracks being loaded, contain reference to which assembl(y/ies)
they belong to */
],
"aggregateTextSearchAdapters": [
/* optional array of text search adapters */
],
"defaultSession": {
/* optional default session */
}
}

The most important thing to configure are your assemblies and your tracks.

Configuring assemblies

An assembly configuration includes the "name" of your assembly, any "aliases" that might be associated with that assembly e.g. GRCh37 is sometimes seen as an alias for hg19, and then a "sequence" configuration containing a reference sequence track config. This is provides a special "track" that is outside the normal track config.

Here is a complete config.json file containing only an hg19 assembly:

{
"assemblies": [
{
"name": "hg19",
"aliases": ["GRCh37"],
"sequence": {
"type": "ReferenceSequenceTrack",
"trackId": "hg19_config",
"adapter": {
"type": "BgzipFastaAdapter",
"fastaLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz",
"locationType": "UriLocation"
},
"faiLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.fai",
"locationType": "UriLocation"
},
"gziLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.gzi",
"locationType": "UriLocation"
}
},
"rendering": {
"type": "DivSequenceRenderer"
}
},
"refNameAliases": {
"adapter": {
"type": "RefNameAliasAdapter",
"location": {
"uri": "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/hg19_aliases.txt",
"locationType": "UriLocation"
}
}
}
}
]
}

Configuring reference name aliasing

Reference name aliasing is a process to make chromosomes that are named slightly differently but which refer to the same thing render properly.

The refNameAliases in the above config provides this functionality:

"refNameAliases": {
"adapter": {
"type": "RefNameAliasAdapter",
"location": {
"uri": "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/hg19_aliases.txt",
"locationType": "UriLocation"
}
}
}

The hg19_aliases then is a tab delimited file that looks like the following; the first column should be the names that are in your FASTA sequence, and the rest of the columns are aliases:

1   chr1
2 chr2
3 chr3
4 chr4
5 chr5
6 chr6
7 chr7
8 chr8
9 chr9
10 chr10
11 chr11
12 chr12
13 chr13
14 chr14
15 chr15
16 chr16
17 chr17
18 chr18
19 chr19
20 chr20
21 chr21
22 chr22
X chrX
Y chrY
M chrM MT
note

"chromAliases" files from UCSC match this format.

Adding an assembly with the CLI

Generally we add a new assembly with the CLI using something like:

## use samtools to make a fasta index for your reference genome
samtools faidx myfile.fa

## install the jbrowse CLI
npm install -g @jbrowse/cli

## add the assembly using the jbrowse CLI, this will automatically copy the
myfile.fa and myfile.fa.fai to your data folder at /var/www/html/jbrowse2
jbrowse add-assembly myfile.fa --load copy --out /var/www/html/jbrowse2

See our configure JBrowse using the cli tutorial for more in-depth instructions, or more information on the add-assembly command through our CLI tools guide.

note

Assemblies can also be added graphically using the assembly manager when you are using the admin-server. See how to configure JBrowse using the GUI for more details.

Assembly config

Because JBrowse 2 can potentially have multiple assemblies loaded at once, it needs to make sure each track is associated with an assembly.

To do this, we make assemblies a special part of the config, and make sure each track refers to which genome assembly it uses.

Example config with hg19 genome assembly loaded

Here is a complete config.json that has the hg19 genome loaded:

{
"assemblies": [
{
"name": "hg19",
"aliases": ["GRCh37"],
"sequence": {
"type": "ReferenceSequenceTrack",
"trackId": "refseq_track",
"adapter": {
"type": "BgzipFastaAdapter",
"fastaLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz",
"locationType": "UriLocation"
},
"faiLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.fai",
"locationType": "UriLocation"
},
"gziLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.gzi",
"locationType": "UriLocation"
}
},
"rendering": {
"type": "DivSequenceRenderer"
}
},
"refNameAliases": {
"adapter": {
"type": "RefNameAliasAdapter",
"location": {
"uri": "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/hg19_aliases.txt",
"locationType": "UriLocation"
}
}
}
}
]
}

The top level config is an array of assemblies; each assembly contains:

  • name - a name to refer to the assembly by. each track that is related to this assembly references this name
  • aliases - sometimes genome assemblies have aliases like hg19, GRCh37, b37p5, etc. while there may be small differences between these different sequences, they often largely have the same coordinates, so you might want to be able to associate tracks from these different assemblies together. The assembly aliases are most helpful when loading from a UCSC trackHub which specifies the genome assembly names it uses, so you can connect to a UCSC trackHub if your assembly name or aliases match.
  • sequence - this is a complete "track" definition for your genome assembly. we specify that it is a track of type ReferenceSequenceTrack, give it a trackId, and an adapter configuration. an adapter configuration can specify IndexedFastaAdapter (fasta.fa and fasta.fai), BgzipFastaAdapter (fasta.fa.gz, fasta.fa.gz.fai, fasta.gz.gzi), ChromSizesAdapter (which fetches no sequences, just chromosome names)

ReferenceSequenceTrack

Example ReferenceSequenceTrack config, which as above, is specified as the child of the assembly section of the config:

{
"type": "ReferenceSequenceTrack",
"trackId": "refseq_track",
"adapter": {
"type": "BgzipFastaAdapter",
"fastaLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz",
"locationType": "UriLocation"
},
"faiLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.fai",
"locationType": "UriLocation"
},
"gziLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.gzi",
"locationType": "UriLocation"
}
},
"rendering": {
"type": "DivSequenceRenderer"
}
}

BgzipFastaAdapter

A bgzip FASTA format file is generated by

bgzip -i sequence.fa
samtools faidx sequence.fa.gz

### above commands generates the following three files
sequence.fa.gz
sequence.fa.gz.gzi
sequence.fa.gz.fai

These are loaded into a BgzipFastaAdapter as follows

{
"type": "BgzipFastaAdapter",
"fastaLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz",
"locationType": "UriLocation"
},
"faiLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.fai",
"locationType": "UriLocation"
},
"gziLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.gzi",
"locationType": "UriLocation"
}
}

IndexedFastaAdapter

An indexed FASTA file is similar to the above, but the sequence is not compressed

samtools faidx sequence.fa

### above commands generate the .fa and .fai files
sequence.fa
sequence.fa.fai

These are loaded into a IndexedFastaAdapter as follows

{
"type": "IndexedFastaAdapter",
"fastaLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa",
"locationType": "UriLocation"
},
"faiLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.fai",
"locationType": "UriLocation"
}
}
FASTA Header Location

Meta-information on the assembly can be specified by adding the following section to either the IndexedFastaAdapter or BgzipFastaAdapter configuration. One option for the contents of this metadata is the FFRGS (Fair Formatted Reference Genome Standard) header specification for FASTA files can be found here, however, just the raw plaintext is displayed for this file so the format is not strict.

  "metadataLocation": {
"uri": "https://raw.githubusercontent.com/FFRGS/FFRGS-Specification/main/examples/example.yaml",
"locationType": "UriLocation"
}

TwoBitAdapter

The UCSC twoBit adapter is also supported. Note however that the 2bit format has a longer startup time than other adapters because there is a larger upfront parsing time.

{
"type": "TwoBitAdapter",
"twoBitLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.2bit",
"locationType": "UriLocation"
}
}

Optionally you can specify a .chrom.sizes file which will speed up loading the 2bit especially if it has many chromosomes in it

{
"type": "TwoBitAdapter",
"twoBitLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.2bit",
"locationType": "UriLocation"
},
"chromSizesLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.chrom.sizes",
"locationType": "UriLocation"
}
}

Track configurations

All tracks can contain:

  • trackId - internal track ID, must be unique
  • name - displayed track name
  • assemblyNames - an array of assembly names a track is associated with, often just a single assemblyName
  • category - (optional) array of categories to display in a hierarchical track selector

Example config.json containing a track config:

{
"assemblies": [
{
"name": "hg19",
"aliases": ["GRCh37"],
"sequence": {
"type": "ReferenceSequenceTrack",
"trackId": "Pd8Wh30ei9R",
"adapter": {
"type": "BgzipFastaAdapter",
"fastaLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz",
"locationType": "UriLocation"
},
"faiLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.fai",
"locationType": "UriLocation"
},
"gziLocation": {
"uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.gzi",
"locationType": "UriLocation"
}
}
}
}
],
"tracks": [
{
"type": "FeatureTrack",
"trackId": "repeats_hg19",
"name": "Repeats",
"assemblyNames": ["hg19"],
"category": ["Annotation"],
"adapter": {
"type": "BigBedAdapter",
"bigBedLocation": {
"uri": "https://jbrowse.org/genomes/hg19/repeats.bb",
"locationType": "UriLocation"
}
}
}
]
}

AlignmentsTrack config

Example AlignmentsTrack config:

{
"trackId": "my_alignments_track",
"name": "My Alignments",
"assemblyNames": ["hg19"],
"type": "AlignmentsTrack",
"adapter": {
"type": "BamAdapter",
"bamLocation": {
"uri": "http://yourhost/file.bam",
"locationType": "UriLocation"
},
"index": {
"location": {
"uri": "http://yourhost/file.bam.bai",
"locationType": "UriLocation"
}
}
}
}
BamAdapter configuration options
  • bamLocation - a 'file location' for the BAM
  • index - a subconfiguration schema containing
    • indexType: options BAI or CSI. default: BAI
    • location: a 'file location' of the index

Example BamAdapter config:

{
"type": "BamAdapter",
"bamLocation": {
"uri": "http://yourhost/file.bam",
"locationType": "UriLocation"
},
"index": {
"location": {
"uri": "http://yourhost/file.bam.bai",
"locationType": "UriLocation"
}
}
}
CramAdapter configuration options
  • cramLocation - a 'file location' for the CRAM
  • craiLocation - a 'file location' for the CRAI

Example CramAdapter config:

{
"type": "CramAdapter",
"cramLocation": {
"uri": "http://yourhost/file.cram",
"locationType": "UriLocation"
},
"craiLocation": {
"uri": "http://yourhost/file.cram.crai",
"locationType": "UriLocation"
}
}

HicTrack config

Example Hi-C track config:

{
"type": "HicTrack",
"trackId": "hic",
"name": "Hic Track",
"assemblyNames": ["hg19"],
"adapter": {
"type": "HicAdapter",
"hicLocation": {
"uri": "https://s3.amazonaws.com/igv.broadinstitute.org/data/hic/intra_nofrag_30.hic",
"locationType": "UriLocation"
}
}
}
HicAdapter config

We just simply supply a hicLocation currently for the HicAdapter:

{
"type": "HicAdapter",
"hicLocation": {
"uri": "https://s3.amazonaws.com/igv.broadinstitute.org/data/hic/intra_nofrag_30.hic",
"locationType": "UriLocation"
}
}
HicRenderer config
  • baseColor - the default baseColor of the Hi-C plot is red #f00, you can change it to blue so then the shading will be done in blue with #00f
  • color - this is a color callback that adapts the current Hi-C contact feature with the baseColor to generate a shaded block. The default color callback function is jexl:baseColor.alpha(Math.min(1,count/(maxScore/20))).hsl().string() where it receives the count for a particular block, the maxScore over the region, and the baseColor from the baseColor config

VariantTrack config

  • defaultRendering - options: 'pileup' or 'svg'. default 'svg'
  • adapter - a variant type adapter config e.g. a VcfTabixAdapter

Example config:

{
"type": "VariantTrack",
"trackId": "my track",
"name": "My Variants",
"assemblyNames": ["hg19"],
"adapter": {
"type": "VcfTabixAdapter",
"vcfGzLocation": {
"uri": "http://yourhost/file.vcf.gz",
"locationType": "UriLocation"
},
"index": {
"location": {
"uri": "http://yourhost/file.vcf.gz.tbi",
"locationType": "UriLocation"
}
}
}
}
VcfTabixAdapter configuration options
  • vcfGzLocation - a 'file location' for the BigWig
  • index - a subconfiguration schema containing
    • indexType: options TBI or CSI. default TBI
    • location: the location of the index

Example VcfTabixAdapter adapter config:

{
"type": "VcfTabixAdapter",
"vcfGzLocation": {
"uri": "http://yourhost/file.vcf.gz",
"locationType": "UriLocation"
},
"index": {
"location": {
"uri": "http://yourhost/file.vcf.gz.tbi",
"locationType": "UriLocation"
}
}
}

MultiQuantitativeTrack config

Example MultiQuantitativeTrack config:

{
"type": "MultiQuantitativeTrack",
"trackId": "microarray_multi",
"name": "MultiWig",
"category": ["ENCODE bigWigs"],
"assemblyNames": ["hg19"],
"adapter": {
"type": "MultiWiggleAdapter",
"bigWigs": [
"https://www.encodeproject.org/files/ENCFF055ZII/@@download/ENCFF055ZII.bigWig",
"https://www.encodeproject.org/files/ENCFF826HEW/@@download/ENCFF826HEW.bigWig",
"https://www.encodeproject.org/files/ENCFF858LIM/@@download/ENCFF858LIM.bigWig",
"https://www.encodeproject.org/files/ENCFF425TNW/@@download/ENCFF425TNW.bigWig",
"https://www.encodeproject.org/files/ENCFF207RBY/@@download/ENCFF207RBY.bigWig",
"https://www.encodeproject.org/files/ENCFF289CTN/@@download/ENCFF289CTN.bigWig",
"https://www.encodeproject.org/files/ENCFF884IEG/@@download/ENCFF884IEG.bigWig",
"https://www.encodeproject.org/files/ENCFF495SBQ/@@download/ENCFF495SBQ.bigWig",
"https://www.encodeproject.org/files/ENCFF959EZF/@@download/ENCFF959EZF.bigWig",
"https://www.encodeproject.org/files/ENCFF926YZX/@@download/ENCFF926YZX.bigWig",
"https://www.encodeproject.org/files/ENCFF269CHA/@@download/ENCFF269CHA.bigWig",
"https://www.encodeproject.org/files/ENCFF857KTJ/@@download/ENCFF857KTJ.bigWig",
"https://www.encodeproject.org/files/ENCFF109KCQ/@@download/ENCFF109KCQ.bigWig",
"https://www.encodeproject.org/files/ENCFF942TZX/@@download/ENCFF942TZX.bigWig",
"https://www.encodeproject.org/files/ENCFF140HPM/@@download/ENCFF140HPM.bigWig",
"https://www.encodeproject.org/files/ENCFF305JRR/@@download/ENCFF305JRR.bigWig",
"https://www.encodeproject.org/files/ENCFF739FDJ/@@download/ENCFF739FDJ.bigWig",
"https://www.encodeproject.org/files/ENCFF518OJP/@@download/ENCFF518OJP.bigWig",
"https://www.encodeproject.org/files/ENCFF810HHS/@@download/ENCFF810HHS.bigWig",
"https://www.encodeproject.org/files/ENCFF939JSB/@@download/ENCFF939JSB.bigWig",
"https://www.encodeproject.org/files/ENCFF041TAK/@@download/ENCFF041TAK.bigWig"
]
}
}
General MultiQuantitativeTrack options

You can pass an array of urls for bigWig files to the "bigWigs" slot for MultiWiggleAdapter, or an array of complete subtrack adapter configs to the "subadapters" slot for MultiWiggleAdapter. The subadapters slot can contain extra fields such as color, which is interpreted as the subtrack color, and any accessory fields like "group" that might help end users organize the subtracks.

Example with group field:

{
"type": "MultiQuantitativeTrack",
"trackId": "microarray_multi_groups",
"name": "MultiWig (groups)",
"category": ["ENCODE bigWigs"],
"assemblyNames": ["hg19"],
"adapter": {
"type": "MultiWiggleAdapter",
"subadapters": [
{
"type": "BigWigAdapter",
"name": "k1",
"bigWigLocation": {
"uri": "https://www.encodeproject.org/files/ENCFF055ZII/@@download/ENCFF055ZII.bigWig"
},
"group": "group1"
},
{
"type": "BigWigAdapter",
"name": "k2",
"bigWigLocation": {
"uri": "https://www.encodeproject.org/files/ENCFF826HEW/@@download/ENCFF826HEW.bigWig"
},
"group": "group2"
}
]
}
}

The "name" or "source" field on the subadapters will be used as the subtrack label (where, "source" will be given priority over "name" if specified)

QuantitativeTrack config

Example QuantitativeTrack config:

{
"trackId": "my_wiggle_track",
"name": "My Wiggle Track",
"assemblyNames": ["hg19"],
"type": "QuantitativeTrack",
"adapter": {
"type": "BigWig",
"bigWigLocation": {
"uri": "http://yourhost/file.bw",
"locationType": "UriLocation"
}
}
}
General QuantitativeTrack options
  • scaleType - options: linear, log, to display the coverage data. default: linear
  • adapter - an adapter that returns numeric signal data, e.g. feature.get('score')
Autoscale options for QuantitativeTrack

Options for autoscale:

  • local - min/max values of what is visible on the screen
  • global - min/max values in the entire dataset
  • localsd - mean value +- N stddevs of what is visible on screen
  • globalsd - mean value +/- N stddevs of everything in the dataset
Score min/max for QuantitativeTrack

These options overrides the autoscale options and provides a minimum or maximum value for the autoscale bar:

  • minScore
  • maxScore
QuantitativeTrack drawing options
  • inverted - draws upside down
  • defaultRendering - can be density, xyplot, or line
  • summaryScoreMode - options: min, max, whiskers
QuantitativeTrack renderer options
  • filled - fills in the XYPlot histogram
  • bicolorPivot - options: numeric, mean, none. default: numeric
  • bicolorPivotValue - number at which the color switches from posColor to negColor. default: 0
  • color - color or color callback for drawing the values. overrides posColor/negColor. default: none
  • posColor - color to draw "positive" values. default: red
  • negColor - color to draw "negative" values. default: blue
  • clipColor - color to draw "clip" indicator. default: red
BigWigAdapter options
  • bigWigLocation - a 'file location' for the bigwig

Example BigWig adapter config:

{
"type": "BigWig",
"bigWigLocation": {
"uri": "http://yourhost/file.bw",
"locationType": "UriLocation"
}
}

SyntenyTrack config

Example SyntenyTrack config:

{
"type": "SyntenyTrack",
"trackId": "dotplot_track",
"assemblyNames": ["YJM1447", "R64"],
"name": "dotplot",
"adapter": {
"type": "PAFAdapter",
"pafLocation": {
"uri": "https://s3.amazonaws.com/jbrowse.org/genomes/yeast/YJM1447_vs_R64.paf"
},
"assemblyNames": ["YJM1447", "R64"]
}
}

We can load a SyntenyTrack from PAF with the CLI e.g. with:

jbrowse add-track myfile.paf --type SyntenyTrack --assemblyNames \
grape,peach --load copy --out /var/www/html/jbrowse2

The first assembly is the "target" and the second assembly is the "query."

See how to configure JBrowse using the CLI for more ways to load synteny tracks with the CLI.

PAFAdapter config

The PAF adapter reflects a pairwise alignment, and is outputted by tools like minimap2. It can be used for SyntenyTracks:

{
"type": "PAFAdapter",
"pafLocation": {
"uri": "https://s3.amazonaws.com/jbrowse.org/genomes/yeast/YJM1447_vs_R64.paf"
},
"assemblyNames": ["YJM1447", "R64"]
}

Slots

  • pafLocation - the location of the PAF file. The pafLocation can refer to a gzipped or unzipped delta file. It will be read into memory entirely as it is not an indexed file format.
  • assemblyNames - list of assembly names, typically two (first in list is target, second is query)
  • queryAssembly - alternative to assemblyNames: just the assemblyName of the query
  • targetAssembly - alternative to assemblyNames: just the assemblyName of the target

DeltaAdapter config

The DeltaAdapter is used to load .delta files from MUMmer/nucmer. It can be used for SyntenyTracks:

{
"type": "DeltaAdapter",
"deltaLocation": {
"uri": "https://s3.amazonaws.com/jbrowse.org/genomes/yeast/YJM1447_vs_R64.paf"
},
"assemblyNames": ["YJM1447", "R64"]
}

Slots

  • deltaLocation - the location of the delta file. The deltaLocation can refer to a gzipped or unzipped delta file. It will be read into memory entirely as it is not an indexed file format.
  • assemblyNames - list of assembly names, typically two (first in list is target, second is query)
  • queryAssembly - alternative to assemblyNames: just the assemblyName of the query
  • targetAssembly - alternative to assemblyNames: just the assemblyName of the target

ChainAdapter config

The ChainAdapter is used to load .chain files from MUMmer/nucmer. It can be used for SyntenyTracks:

{
"type": "DeltaAdapter",
"deltaLocation": {
"uri": "https://s3.amazonaws.com/jbrowse.org/genomes/yeast/YJM1447_vs_R64.paf"
},
"assemblyNames": ["YJM1447", "R64"]
}

Slots

  • chainLocation - the location of the UCSC chain file. The chainLocation can refer to a gzipped or unzipped delta file. It will be read into memory entirely as it is not an indexed file format.
  • assemblyNames - list of assembly names, typically two (first in list is target, second is query)
  • queryAssembly - alternative to assemblyNames: just the assemblyName of the query
  • targetAssembly - alternative to assemblyNames: just the assemblyName of the target

MCScanAnchorsAdapter

The .anchors file from MCScan refers to pairs of homologous genes and can be loaded into synteny tracks in JBrowse 2:

{
"type": "MCScanAnchorsAdapter",
"mcscanAnchorsLocation": {
"uri": "https://s3.amazonaws.com/jbrowse.org/genomes/synteny/grape.peach.anchors.gz"
},
"bed1Location": {
"uri": "https://s3.amazonaws.com/jbrowse.org/genomes/synteny/grape_vs_peach/grape.bed.gz"
},
"bed2Location": {
"uri": "https://s3.amazonaws.com/jbrowse.org/genomes/synteny/grape_vs_peach/peach.bed.gz"
},
"assemblyNames": ["grape", "peach"]
}

This guide shows a demonstration of how to create the anchors and bed files (the .bed files are intermediate steps in creating the anchors files and are required by the MCScanAnchorsAdapter).

Slots:

  • mcscanAnchorsLocation - the location of the .anchors file from the MCScan workflow. The .anchors file has three columns. It can be gzipped or ungzipped, and is read into memory whole
  • bed1Location - the location of the first assemblies .bed file from the MCScan workflow. It can be gzipped or ungzipped, and is read into memory whole. This would refer to the gene names on the "left" side of the .anchors file.
  • bed2Location - the location of the second assemblies .bed file from the MCScan workflow. It can be gzipped or ungzipped, and is read into memory whole. This would refer to the gene names on the "right" side of the .anchors file.

MCScanSimpleAnchorsAdapter

The "simple" .anchors.simple file from MCScan refers to pairs of homologous genes and can be loaded into synteny tracks in JBrowse 2:

{
"type": "MCScanSimpleAnchorsAdapter",
"mcscanSimpleAnchorsLocation": {
"uri": "https://s3.amazonaws.com/jbrowse.org/genomes/synteny/grape.peach.anchors.simple.gz"
},
"bed1Location": {
"uri": "https://s3.amazonaws.com/jbrowse.org/genomes/synteny/grape_vs_peach/grape.bed.gz"
},
"bed2Location": {
"uri": "https://s3.amazonaws.com/jbrowse.org/genomes/synteny/grape_vs_peach/peach.bed.gz"
},
"assemblyNames": ["grape", "peach"]
}

This guide shows a demonstration of how to create the anchors and bed files (the .bed files are intermediate steps in creating the anchors.simple files and are required by the MCScanSimpleAnchorsAdapter)

Slots:

  • mcscanSimpleAnchorsLocation - the location of the .anchors.simple file from the MCScan workflow (this file has 5 columns, start and end gene from bed1, start and end genes from bed2, and score). It can be gzipped or ungzipped, and is read into memory whole
  • bed1Location - the location of the first assemblies .bed file from the MCScan workflow. It can be gzipped or ungzipped, and is read into memory whole. This would refer to the gene names on the "left" side of the .anchors file.
  • bed2Location - the location of the second assemblies .bed file from the MCScan workflow. It can be gzipped or ungzipped, and is read into memory whole. This would refer to the gene names on the "right" side of the .anchors file.

Advanced adapters

There are two useful adapter types that can be used for more advanced use cases, such as generating configuration for data returned by an API. These are the FromConfigAdapter and FromConfigSequenceAdapter. They can be used as the adapter value for any track type.

FromConfigAdapter

This adapter can be used to generate features directly from values stored in the configuration.

Example FromConfigAdapter:

{
"type": "FromConfigAdapter",
"features": [
{
"refName": "ctgA",
"uniqueId": "alias1",
"aliases": ["A", "contigA"]
},
{
"refName": "ctgB",
"uniqueId": "alias2",
"aliases": ["B", "contigB"]
}
]
}
FromConfigSequenceAdapter

Similar behavior to FromConfigAdapter, with a specific emphasis on performance when the features are sequences.

Example FromConfigSequenceAdapter:

{
"type": "FromConfigSequenceAdapter",
"features": [
{
"refName": "SEQUENCE_1",
"uniqueId": "firstId",
"start": 0,
"end": 33,
"seq": "CCAAGATCTAAGATGTCAACACCTATCTGCTCA"
},
{
"refName": "SEQUENCE_2",
"uniqueId": "secondId",
"start": 0,
"end": 44,
"seq": "CCGAACCACAGGCCTATGTTACCATTGGAAAGCTCACCTTCCCG"
}
]
}

Text searching

Text searching appears in two forms: per-track indexes and aggregate indexes which search across multiple tracks.

Aggregate indexes may look like this:

{
"aggregateTextSearchAdapters": [
{
"type": "TrixTextSearchAdapter",
"textSearchAdapterId": "hg19-index",
"ixFilePath": {
"uri": "https://jbrowse.org/genomes/hg19/trix/hg19.ix",
"locationType": "UriLocation"
},
"ixxFilePath": {
"uri": "https://jbrowse.org/genomes/hg19/trix/hg19.ixx",
"locationType": "UriLocation"
},
"metaFilePath": {
"uri": "https://jbrowse.org/genomes/hg19/trix/meta.json",
"locationType": "UriLocation"
},
"assemblyNames": ["hg19"]
}
}

An example per-track config may look like this:

{
"trackId":"yourtrack",
"name":"Track name",
"adapter":{
"type": "Gff3TabixAdapter",
"gffGzLocation": { "uri":"yourfile.gff.gz",
"locationType": "UriLocation" }
"index":{ "location": { "uri":"yourfile.gff.gz.tbi",
"locationType": "UriLocation" } }
},
"textSearching": {
"textSearchAdapter": {
"type": "TrixTextSearchAdapter",
"textSearchAdapterId": "hg19-index",
"ixFilePath": {
"uri": "https://jbrowse.org/genomes/hg19/trix/hg19.ix",
"locationType": "UriLocation"
},
"ixxFilePath": {
"uri": "https://jbrowse.org/genomes/hg19/trix/hg19.ixx",
"locationType": "UriLocation"
},
"metaFilePath": {
"uri": "https://jbrowse.org/genomes/hg19/trix/meta.json",
"locationType": "UriLocation"
},
"assemblyNames": ["hg19"]
},
"indexingAttributes": ["Name","ID"],
"indexingFeatureTypesToExclude": ["CDS","exon"]
}
}

Information on generating trix indexes via the CLI can be found here.

TrixTextSearchAdapter config

The trix search index is the current file format for name searching.

It is based on the UCSC trix file format described here https://genome.ucsc.edu/goldenPath/help/trix.html.

To create trix indexes you can use our command line tools. More info can be found at our jbrowse text-index guide. This tool will automatically generate a config like this. The config slots are described below for details:

{
"textSearchAdapter": {
"type": "TrixTextSearchAdapter",
"textSearchAdapterId": "gff3tabix_genes-index",
"ixFilePath": {
"uri": "trix/gff3tabix_genes.ix",
"locationType": "UriLocation"
},
"ixxFilePath": {
"uri": "trix/gff3tabix_genes.ixx",
"locationType": "UriLocation"
},
"metaFilePath": {
"uri": "trix/gff3tabix_genes_meta.json",
"locationType": "UriLocation"
}
}
}
  • ixFilePath - the location of the trix ix file
  • ixxFilePath - the location of the trix ixx file
  • metaFilePath - the location of the metadata json file for the trix index

JBrowse1TextSearchAdapter config

This is more uncommon, but allows back compatibility with a JBrowse1 names index created by generate-names.pl:

{
"textSearchAdapter": {
"type": "JBrowse1TextSearchAdapter",
"textSearchAdapterId": "generate-names-index",
"namesIndexLocation": {
"uri": "/names",
"locationType": "UriLocation"
}
}
}
  • namesIndexLocation - the location of the JBrowse1 names index data directory

DotplotView config

It is recommended to use the DotplotView's importform or a session spec to initialize a dotplot view.

LinearSyntenyView config

It is recommended to use the LinearSyntenyView's importform or a session spec to initialize a linear synteny view.

Configuring the theme

Color

The color scheme as well as some sizing options can be configured via the theme. This is done via a top-level configuration in the config file. For example:

{
"configuration": {
"theme": {
"palette": {
"primary": {
"main": "#4400a6"
}
}
}
}
}

JBrowse uses 4 colors that can be changed. For example, this is the default theme:

Example screenshot showing the default theme
Figure: Example screenshot showing the default theme
Example screenshot showing the customized theme
Figure: Example screenshot showing the customized theme

The customized theme screenshot uses the below configuration:

Color codeColor
Primary#311b92Deep purple
Secondary#0097a7Cyan
Tertiary#f57c00Orange
Quaternary#d50000Red
{
"configuration": {
"theme" :{
"palette": {
"primary": {
"main": "#311b92"
},
"secondary": {
"main": "#0097a7"
},
"tertiary": {
"main": "#f57c00"
},
"quaternary": {
"main": "#d50000"
}
}
}
}

It is also possible to supply a custom logo to be displayed in the top right corner of the app instead of the JBrowse 2 logo. To do this, store a SVG file containing your logo on your server, and specify the path in your configuration:

{
"configuration": {
"logoPath": {
"uri": "path/to/my/custom-logo.svg"
}
}
}

The dimensions of the logo should be 150x48px.

Sizing

You can also change some sizing options by specifying the "typography" (to change font size) and "spacing" (to change the amount of space between elements) options:

{
"theme": {
"typography": { "fontSize": 10 },
"spacing": 2
}
}

Advanced

JBrowse uses Material-UI for its theming. You can read more about Material-UI themes here. Generally, most options you could pass to Material-UI's createMuiTheme should work in the theme configuration.

Disabiling analytics

This is done via adding a field in the global configuration in the config file. For example:

{
"configuration": {
"disableAnalytics": true
}
}

Configuration callbacks

We use Jexl for defining configuration callbacks.

An example of a Jexl configuration callback might look like this:

"color": "jexl:get(feature,'strand')==-1?'red':'blue'"

The notation get(feature,'strand') is the same as feature.get('strand') in javascript code.

We have a number of other functions, such as:

Feature operations - get

jexl: get(feature, 'start') // start coordinate, 0-based half open
jexl: get(feature, 'end') // end coordinate, 0-based half open
jexl: get(feature, 'refName') // chromosome or reference sequence name
jexl: get(feature, 'CIGAR') // BAM or CRAM feature CIGAR string
jexl: get(feature, 'seq') // BAM or CRAM feature sequence
jexl: get(feature, 'type') // feature type e.g. mRNA or gene

Feature operations - getTag

The getTag function smooths over slight differences in BAM and CRAM features to access their tags

jexl: getTag(feature, 'MD') // fetches MD string from BAM or CRAM feature
jexl: getTag(feature, 'HP') // fetches haplotype tag from BAM or CRAM feature

String functions

jexl: charAt('abc', 2) // c
jexl: charCodeAt(' ', 0) // 32
jexl: codePointAt(' ', 0) // 32
jexl: startsWith('kittycat', 'kit') // true
jexl: endsWith('kittycat', 'cat') // true
jexl: padStart('cat', 8, 'kitty') // kittycat
jexl: padEnd('kitty', 8, 'cat') // kittycat
jexl: replace('kittycat', 'cat', '') // kitty
jexl: replaceAll('kittycatcat', 'cat', '') // kitty
jexl: slice('kittycat', 5) // cat
jexl: substring('kittycat', 0, 5) // kitty
jexl: trim(' kitty ') // kitty, whitespace trimmed
jexl: trimStart(' kitty ') // kitty, starting whitespace trimmed
jexl: trimEnd(' kitty ') // kitty, ending whitespace trimmed
jexl: toUpperCase('kitty') // KITTY
jexl: toLowerCase('KITTY') // kitty
jexl: split('KITTY KITTY', ' ') // ['KITTY', 'KITTY']

Math functions

jexl: max(0, 2)
jexl: min(0, 2)
jexl: sqrt(4)
jexl: ceil(0.5)
jexl: floor(0.5)
jexl: round(0.5)
jexl: abs(-0.5)
jexl: log10(50000)
jexl: parseInt('2')
jexl: parseFloat('2.054')

Console logging

jexl: log(feature) // console.logs output and returns value
jexl: cast({ mRNA: 'green', pseudogene: 'purple' })[get(feature, 'type')] // returns either green or purple depending on feature type

Binary operators

jexl: get(feature, 'flags') & 2 // bitwise and to check if BAM or CRAM feature flags has 2 set

Customizing the feature details panel

Every track has a configuration called formatDetails.

Here is an example track with a formatter:

{
"type": "FeatureTrack",
"trackId": "genes",
"assemblyNames": ["hg19"],
"name": "Genes",
"formatDetails": {
"feature": "jexl:{name:'<a href=https://google.com/?q='+feature.name+'>'+feature.name+'</a>',newfield:'Custom contents here: '+feature.name,type:undefined }"
},
"adapter": {
"type": "Gff3TabixAdapter",
"gffGzLocation": {
"uri": "volvox.sort.gff3.gz"
},
"index": {
"location": {
"uri": "volvox.sort.gff3.gz.tbi"
}
}
}
}
Example screenshot showing customized feature detail panel with links
Figure: Example screenshot showing customized feature detail panel with links

This feature formatter changes the "name" field in the feature detail panel to have a link to a google search for that feature's name. This can be used to link to gene pages for example as well.

In addition, this example also adds a custom field called "newfield" and removes e.g. "type" from being displayed.

The schema for formatDetails is:

  • feature - customizes the top-level feature
  • subfeatures - customizes the subfeatures, recursively up to depth
  • depth - depth to customize the subfeatures to, default 1

The general way this is done is by making a jexl callback either or both of feature and subfeatures (if you want both feature and subfeatures, you can copy the same thing to both config slots).

The callback returns an object where the keys of the object are what you want to replace.

In the example above we return an object with:

  • name - customizes the name field with a link in the feature details
  • type - we make this undefined, which removes it from the feature details
  • newfield - this generates a new field in the feature details

Making sophisticated customizations to feature detail panels

If your feature detail panel customization is complex, you can create a custom javascript function in a plugin that is registered with the jexl system e.g.

class MyPlugin {
install() {}
configure(pluginManager: PluginManager) {
pluginManager.jexl.addFunction('formatName', feature => {
return `<a href="${feature.name}">${feature.name}</a>`
})
}
}

Then you can use the custom jexl function in your config callbacks as follows:

{
"type": "FeatureTrack",
"trackId": "genes",
"assemblyNames": ["hg19"],
"name": "Genes",
"formatDetails": {
"feature": "jexl:{name:formatName(feature)}"
},
...
}

See our developer guides for more information regarding plugin development.

Configuring plugins

External published plugins can be added to the configuration like so:

{
"plugins": [
{
"name": "GDC",
"url": "https://unpkg.com/jbrowse-plugin-gdc/dist/jbrowse-plugin-gdc.umd.production.min.js"
}
]
}

Published plugins are typically hosted on unpkg and can be referenced as above.

Any tools that are available via that plugin will then be added to JBrowse. You can verify the plugin is installed properly by checking the Plugin Store:

Example screenshot showing how installed plugins are represented in the plugin store interface. Plugins installed via the config are shown with a lock icon, indicating they cannot be removed via the GUI.
Figure: Example screenshot showing how installed plugins are represented in the plugin store interface. Plugins installed via the config are shown with a lock icon, indicating they cannot be removed via the GUI.

If you have an unpublished plugin running locally, you can add that plugin to your configuration using the localhost the plugin is running on:

{
"plugins": [
{
"name": "GDC",
"url": "http://localhost:9000/dist/jbrowse-plugin-gdc.umd.development.js"
}
]
}

Checkout our developer guide for more information on developing plugins, or our plugins page to browse currently published plugins.

Core concepts and intro to pluggable elements

This guide will introduce the JBrowse 2 ecosystem from the developer's point of view. We'll examine the core concepts of how code is packaged and structured, and then go over how to create new plugins and pluggable elements.

Introduction and overview

Let's get a high-level view of the JBrowse 2 ecosystem.

Products and plugins

The JBrowse 2 ecosystem has two main types of top-level artifacts that are published on their own: products and plugins.

Architecture diagram of JBrowse 2, showing how plugins encapsulate views (e.g. LinearGenomeView, DotplotView etc.), tracks (AlignmentsTrack, VariantTrack, etc.), adapters (BamAdapter, VcfTabixAdapter, etc.) and other logic like mobx state tree autoruns that add logic to other parts of the app (e.g. adding context menus)
Figure: Architecture diagram of JBrowse 2, showing how plugins encapsulate views (e.g. LinearGenomeView, DotplotView etc.), tracks (AlignmentsTrack, VariantTrack, etc.), adapters (BamAdapter, VcfTabixAdapter, etc.) and other logic like mobx state tree autoruns that add logic to other parts of the app (e.g. adding context menus)

A "product" is an application of some kind that is published on its own (a web app, an electron app, a CLI app, etc). jbrowse-web, jbrowse-desktop, and jbrowse-cli are products.

A "plugin" is a package of functionality that is designed to "plug in" to a product at runtime to add functionality. These can be written and published by anyone, not just the JBrowse core team. Not all of the products use plugins, but most of them do.

Also, most of the products are pretty standard in the way they are constructed. For example, jbrowse-web is a React web application that is made with Create React App (CRA), and jbrowse-cli is a command-line tool implemented with OCLIF.

This figure summarizes the general architecture of our state model and React component tree
Figure: This figure summarizes the general architecture of our state model and React component tree

Example plugins

You can follow this guide for developing plugins, but you might also want to refer to working versions of plugins on the web now.

This repo contains a template for creating new plugins https://github.com/GMOD/jbrowse-plugin-template.

Here are some examples of working plugins:

  • jbrowse-plugin-ucsc-api probably the simplest plugin example, it demonstrates accessing data from UCSC REST API
  • jbrowse-plugin-gwas a custom plugin to display manhattan plot GWAS data
  • jbrowse-plugin-biothings-api demonstrates accessing data from mygene.info, part of the "biothings API" family
  • jbrowse-plugin-msaview - demonstrates creating a custom view type that doesn't use any conventional tracks
  • jbrowse-plugin-gdc demonstrates accessing GDC cancer data GraphQL API, plus a custom drawer and track type for coloring variants by impact score
  • jbrowse-plugin-systeminformation demonstrates using desktop specific functionality, accessing system node libraries. This desktop specific functionality should use the CJS bundle type (electron doesn't support ESM yet)

You can use these to see how plugins are generally structured, and can use the pluggable elements in them as templates for your own pluggable elements.

Now, let's explore what plugins can do and how they are structured.

What's in a plugin

A plugin is an independently distributed package of code that is designed to "plug in" to a JBrowse application.

It's implemented as a class that extends @jbrowse/core/Plugin. It gets instantiated by the application that it plugs into, and it has an install method and a configure method that the application calls.

This class is distributed as a webpack bundle that exports it to a namespace on the browser's window object specifically for JBrowse plugins. This means it is only possible to have one version of a particular plugin loaded on any given webpage, even if multiple products are loaded and using it on the same page.

It's common for a plugin to use its configure method to set up mobx autoruns or reactions that react to changes in the application's state to modify its behavior.

Plugins often also have their install method add "pluggable elements" into the host JBrowse application. This is how plugins can add new kinds of views, tracks, renderers, and so forth.

Note

Many of the plugins referenced in the following section are found in the JBrowse Github repo.

We encourage you to reference and review the concepts presented here using the functinal and up-to-date plugin code found there.

Pluggable elements

Pluggable elements are pieces of functionality that plugins can add to JBrowse. Examples of pluggable types include:

  • Adapter types
  • Track types
  • View types
  • Display types
  • Renderer types
  • Widgets
  • RPC calls
  • Extension points
  • Internet account types
  • Connection types
  • Text search adapter types
  • Extension points
  • Add track workflow

In additional to creating plugins that create new adapters, track types, etc. note that you can also wrap the behavior of another track so these elements are composable.

For example, we can have adapters that perform calculations on the results of another adapter, views that contains other subviews, and tracks that contain other tracks, leading to a lot of interesting behavior.

Let's dive further into these details, and look at some examples.

View types

Creating view types is one of the most powerful features of JBrowse 2, because it allows us to put entirely different visualizations in the same context as the standard linear-genome-view.

We have demonstrated a couple new view types in JBrowse 2 already, including:

  • LinearGenomeView - the classic linear view of a genome
  • CircularView - a Circos-like circular whole genome view
  • DotplotView - a comparative 2-D genome view
  • SvInspectorView - superview containing CircularView and SpreadsheetView subviews
  • And more!

We think the boundaries for this are just your imagination, and there can also be interplay between view types e.g. popup dotplot from a linear view, etc.

Adapters

Adapters are parsers for a given data format. We will review what adapters the alignments plugin has (to write your own adapter, see creating adapters).

Example adapters: the @jbrowse/plugin-alignments plugin creates multiple adapter types:

  • BamAdapter - This adapter uses the @gmod/bam NPM module, and adapts it for use by the browser.
  • CramAdapter - This adapter uses the @gmod/cram NPM module. Note that CramAdapter also takes a sequenceAdapter as a subadapter configuration, and uses getSubAdapter to instantiate it
  • SNPCoverageAdapter - this adapter takes a BamAdapter or CramAdapter as a subadapter, and calculates feature coverage from it

Track types

Track types are a high level type that controls how features are drawn. In most cases, a track combines a renderer and an adapter, and can do additional things like:

  • Control what widget pops up on feature click
  • Add extra menu items to the track menu
  • Create subtracks (See AlignmentsTrack)
  • Choose "static-blocks" rendering styles, which keeps contents stable while the user scrolls, or "dynamic-blocks" that update on each scroll

Example tracks: the @jbrowse/plugin-alignments exports multiple track types:

  • SNPCoverageTrack - this track type actually derives from the WiggleTrack type
  • PileupTrack - a track type that draws alignment pileup results
  • AlignmentsTrack - combines SNPCoverageTrack and PileupTrack as "subtracks"

Displays

A display is a method for displaying a particular track in a particular view.

For example, we have a notion of a synteny track type, and the synteny track type has two display models:

  • DotplotDisplay, which is used in the dotplot view
  • LinearSyntenyDisplay, which is used in the linear synteny view

This enables a single track entry to be used in multiple view types e.g. if I run jbrowse add-track myfile.paf, this automatically creates a SyntenyTrack entry in the tracklist, and when this track is opened in the dotplot view, the DotplotDisplay is used for rendering.

Another example of a track type with multiple display types is VariantTrack, which has two display methods

  • LinearVariantDisplay - used in linear genome view
  • ChordVariantDisplay - used in the circular view to draw breakends and structural variants

Renderers

Renderers are a new concept in JBrowse 2, and are related to the concept of server side rendering (SSR), but can be used not just on the server but also in contexts like the web worker (e.g. the webworker can draw the features to an OffscreenCanvas). For more info see creating renderers.

For example, the @jbrowse/plugin-alignments exports several renderer types:

  • PileupRenderer - a renderer type that renders Pileup type display of alignments fetched from the BamAdapter/CramAdapter
  • SNPCoverageRenderer - a renderer that draws the coverage. Note that this renderer derives from the wiggle renderer, but does the additional step of drawing the mismatches over the coverage track
Views, tracks, displays, renderers?

If you're confused about what kind of pluggable element you might need to accomplish your development goals, a way to remember the relationship between these four pluggable elements is as follows:

  1. A view is a container for anything, views typically have tracks (the linear genome view especially)
  2. A track controls the what (kind of data, data adapters used) and how (displays, renderers) of the data you'd like to display, typically within a view
  3. A display is a way you might want to display the data on a track, you might have multiple displays for a given view, for example, displays can determine if a feature is drawn with rectangles or with triangles; displays may have renderers
  4. A renderer controls how the display is presented, for example what might happen when you mouse over a feature

Widgets

Widgets are custom info panels that can show up in side panels, modals, or other places in an app.

Widgets can do multiple types of things, including:

  • Configuration widget
  • Feature detail widget
  • Add track widget
  • Add connection widget
  • etc.

These widgets can be extended via plugins, so for example, the @jbrowse/plugin-alignments extends the BaseFeatureDetailWidget to have custom display of the alignments.

  • AlignmentsFeatureDetailWidget - this provides a custom widget for viewing the feature details of alignments features that customizes the basic feature detail widget

RPC methods

Plugins can register their own RPC methods, which can allow them to offload custom behaviors to a web-worker or server side process.

The wiggle plugin, for example, registers two custom RPC method types:

  • WiggleGetGlobalStats
  • WiggleGetMultiRegionStats

These methods can run in the webworker when available.

Add track workflows

Plugins can register their own React component to display in the "Add track" widget for adding tracks that require custom logic. The Multi-wiggle track is an example of this, it produces a textbox where you can paste a list of files.

A simple addition to the add track workflow:

// plugins/wiggle/MultiWiggleAddTrackWidget/index.jsx

import PluginManager from '@jbrowse/core/PluginManager'
import { AddTrackWorkflowType } from '@jbrowse/core/pluggableElementTypes'
import { types } from 'mobx-state-tree'

// locals
import MultiWiggleWidget from './AddTrackWorkflow'

export default (pm: PluginManager) => {
pm.addAddTrackWorkflowType(
() =>
new AddTrackWorkflowType({
name: 'Multi-wiggle track',
/* in a separate file, export the react component to render within the track widget,
typically a form to collect relevant data for your track */
ReactComponent: MultiWiggleWidget,
stateModel: types.model({}),
}),
)
}

...and ensure you install this component into your larger plugin:

// plugins/wiggle/index.jsx

// ...

export default class WigglePlugin extends Plugin {
name = 'WigglePlugin'

install(pm: PluginManager) {
// ...
MultiWiggleAddTrackWidgetF(pm)
// ...
}
}

Extension points

Extension points are a pluggable element type which allows users to add a callback that is called at an appropriate time.

Checkout the full extension point API or an example for adding context menu items for more detailed information.

The basic API is that producers can say:

const ret = pluginManager.evaluateExtensionPoint('ExtensionPointName', {
value: 1,
})

And consumers can say:

pluginManager.addToExtensionPoint('ExtensionPointName', arg => {
return arg.value + 1
})

pluginManager.addToExtensionPoint('ExtensionPointName', arg => {
return arg.value + 1
})

In this case, arg that is passed in evaluateExtensionPoint calls all the callbacks that have been registered by addToExtensionPoint. If multiple extension points are registered, the return value of the first extension point is passed as the new argument to the second, and so on (they are chained together).

So in the example above, ret would be {value:3} after evaluating the extension point.

Next steps

Now that you have an overview of the different pluggable element types that are available to you, review your understanding of the configuration model, or checkout creating your own pluggable elements for specific guides for making new adapters, tracks, and renderers.

Also checkout the guided tutorial for writing a plugin, which will take you through everything from installation, creating a new pluggable element, and general development tips for working with JBrowse 2.

Understanding the configuration model

This guide will introduce some critical concepts to understanding the configuration model. The configuration model is used to structure the features and data available in a given JBrowse session, and each new pluggable element you create will need its own configuration schema.

Configuration slot types

Our configuration system is "typed" to facilitate graphical editing of the configuration. Each configuration has a "schema" that lists what "configuration slots" it has. Each configuration slot has a name, description, a type, and a value.

Here is a mostly comprehensive list of config types:

  • stringEnum - allows assigning one of a limited set of entries, becomes a dropdown box in the GUI
  • color - allows selecting a color, becomes a color picker in the GUI
  • number - allows entering any numeric value
  • string - allows entering any string
  • integer - allows entering a integer value
  • `boolean
  • frozen - an arbitrary JSON can be specified in this config slot, becomes textarea in the GUI
  • fileLocation - refers to a URL, local file path on desktop, or file blob object in the browser
  • text - allows entering a string, becomes textarea in the GUI
  • stringArray - allows entering a list of strings, becomes a "todolist" style editor in the GUI where you can add or delete things
  • stringArrayMap - allows entering a list of key-value entries

Let's examine the PileupRenderer configuration as an example.

Example config with multiple slot types

This PileupRenderer config contains an example of several different slot types:

// plugins/alignments/src/PileupRenderer/configSchema.ts

import { types } from 'mobx-state-tree'
export default ConfigurationSchema('PileupRenderer', {
color: {
type: 'color',
description: 'the color of each feature in a pileup alignment',
defaultValue: `jexl:get(feature,'strand') == - 1 ? '#8F8FD8' : '#EC8B8B'`,
contextVariable: ['feature'],
},
displayMode: {
type: 'stringEnum',
model: types.enumeration('displayMode', ['normal', 'compact', 'collapse']),
description: 'Alternative display modes',
defaultValue: 'normal',
},
minSubfeatureWidth: {
type: 'number',
description: `the minimum width in px for a pileup mismatch feature. use for
increasing mismatch marker widths when zoomed out to e.g. 1px or
0.5px`,
defaultValue: 0,
},
maxHeight: {
type: 'integer',
description: 'the maximum height to be used in a pileup rendering',
defaultValue: 600,
},
})

Accessing config values

So instead of accessing config.displayMode, we say,

readConfObject(config, 'displayMode')

You might also see in the code like this:

getConf(track, 'maxHeight')

Which would be equivalent to calling,

readConfObject(track.configuration, 'maxHeight')`

Using config callbacks

Config callbacks allow you to have a dynamic color based on some function logic you provide. All config slots can actually become config callback. The arguments that are given to the callback are listed by the 'contextVariable' but must be provided by the calling code (the code reading the config slot). To pass arguments to the a callback we say

readConfObject(config, 'color', { feature })

That implies the color configuration callback will be passed a feature, so the config callback can be a complex function determining the color to use based on various feature attributes.

Example of a config callback

We use Jexl to express callbacks. See https://github.com/TomFrost/Jexl for more details.

There are also more examples and information in our config guide.

If you had a variant track in your config, and wanted to make a custom config callback for color, it might look like this:

{
"type": "VariantTrack",
"trackId": "variant_colors",
"name": "volvox filtered vcf (green snp, purple indel)",
"category": ["VCF"],
"assemblyNames": ["volvox"],
"adapter": {
"type": "VcfTabixAdapter",
"vcfGzLocation": {
"uri": "volvox.filtered.vcf.gz",
"locationType": "UriLocation"
},
"index": {
"location": {
"uri": "volvox.filtered.vcf.gz.tbi",
"locationType": "UriLocation"
}
}
},
"displays": [
{
"type": "LinearVariantDisplay",
"displayId": "volvox_filtered_vcf_color-LinearVariantDisplay",
"renderer": {
"type": "SvgFeatureRenderer",
"color1": "jexl:get(feature,'type')=='SNV'?'green':'purple'" # here we call our jexl function
}
}
]
}

This draws all SNV (single nucleotide variants) as green, and other types as purple (insertion, deletion, other structural variant).

You can also write your own jexl function and call it in the same way in the configuration.

Note

It can be extremely useful to utilize a custom jexl function in the default configuration for a pluggable element type, as you can observe in one of the examples above, the default value of the color slot of the renderer is a jexl function. If you configure your plugin with a custom jexl function, you can use that function as a default value in your various pluggable elements.

Configuration internals

A configuration is a type of mobx-state-tree model, in which leaf nodes are ConfigSlot types, and other nodes are ConfigurationSchema types.

       Schema
/ | \
Slot Schema Slot
| \
Slot Slot

Configurations are all descendants of a single root configuration, which is root.configuration.

Configuration types should always be created by the ConfigurationSchema factory, e.g.:

import { ConfigurationSchema } from '@jbrowse/core/utils/configuration'
const ThingStateModel = types.model('MyThingsState', {
foo: 42,
configuration: ConfigurationSchema('MyThing', {
backgroundColor: {
defaultValue: 'white',
type: 'string',
},
}),
})

An example of a config schema with a sub-config schema is the BamAdapter, with the index sub-config schema:

ConfigurationSchema(
'BamAdapter',
{
bamLocation: {
type: 'fileLocation',
defaultValue: { uri: '/path/to/my.bam', locationType: 'UriLocation' },
},
// this is a sub-config schema
index: ConfigurationSchema('BamIndex', {
indexType: {
model: types.enumeration('IndexType', ['BAI', 'CSI']),
type: 'stringEnum',
defaultValue: 'BAI',
},
location: {
type: 'fileLocation',
defaultValue: {
uri: '/path/to/my.bam.bai',
locationType: 'UriLocation',
},
},
}),
},
{ explicitlyTyped: true },
)

Reading the sub-config schema is as follows

const indexType = readConfObject(config, ['index', 'indexType'])

Alternatively can use

const indexConf = readConfObject(config, ['index'])
indexConf.indexType

However, this may miss default values from the slot, the readConfObject has special logic to fill in the default value.

Creating your own pluggable elements

This guide will walk you through the concepts necessary for creating your own of some of the most common pluggable element types, including adapters, tracks, and renderers.

Simple additions to JBrowse using plugins

Adding a top-level menu

These are the menus that appear in the top bar of JBrowse Web and JBrowse Desktop. By default, there are File, Add, Tools, and Help menus.

You can add your own menu, or you can add menu items or sub-menus to the existing menus and sub-menus. Sub-menus can be arbitrarily deep.

In the above screenshot, the `Add` menu provides quick access to adding a view via the UI; this is a good place
to consider adding your own custom view type.
Figure: In the above screenshot, the `Add` menu provides quick access to adding a view via the UI; this is a good place to consider adding your own custom view type.

You add menus in the configure method of your plugin. Not all JBrowse products will have top-level menus, though. JBrowse Web and JBrowse Desktop have them, but something like JBrowse Linear View (which is an just a single view designed to be embedded in another page) does not. This means you need to check whether or not menus are supported using isAbstractMenuManager in the configure method. This way the rest of the plugin will still work if there is not a menu. Here's an example that adds an "Open My View" item to the Add menu.

import Plugin from '@jbrowse/core/Plugin'
import { isAbstractMenuManager } from '@jbrowse/core/util'
import InfoIcon from '@mui/icons-material/Info'

class MyPlugin extends Plugin {
name = 'MyPlugin'

install(pluginManager) {
// install MyView here
}

configure(pluginManager) {
if (isAbstractMenuManager(pluginManager.rootModel)) {
pluginManager.rootModel.appendToMenu('Add', {
label: 'Open My View',
icon: InfoIcon,
onClick: session => {
session.addView('MyView', {})
},
})
}
}
}

This example uses rootModel.appendToMenu. See top-level menu API for more details on available functions.

Adding menu items to a custom track

If you create a custom track, you can populate the track menu items in it using the trackMenuItems property in the track model. For example:

types
.model({
// model
})
.views(self => ({
trackMenuItems() {
return [
{
label: 'Menu Item',
icon: AddIcon,
onClick: () => {},
},
]
},
}))

If you'd prefer to append your track menu items onto menu items available from the base display, you can grab the trackMenuItems property from the extended model and redefine trackMenuItems with your new Menu Item appended at the end, like so:

types
.model({
// model
})
.views(self => {
const { trackMenuItems: superTrackMenuItems } = self
return {
get trackMenuItems() {
return [
...superTrackMenuItems(),
{
label: 'Menu Item',
icon: AddIcon,
onClick: () => {},
},
]
},
}
})

Adding track context-menu items

When you right-click in a linear track, a context menu will appear if there are any menu items defined for it.

A screenshot of a context menu available on a linear genome view track. Here, we see the context menu of a feature right-clicked on a LinearAlignmentsDisplay.
Figure: A screenshot of a context menu available on a linear genome view track. Here, we see the context menu of a feature right-clicked on a LinearAlignmentsDisplay.

It's possible to add items to that menu, and you can also have different menu items based on if the click was on a feature or not, and based on what feature is clicked. This is done by extending the contextMenuItems view of the display model. Here is an example:

class SomePlugin extends Plugin {
name = 'SomePlugin'

install(pluginManager) {
pluginManager.addToExtensionPoint(
'Core-extendPluggableElement',
pluggableElement => {
if (pluggableElement.name === 'LinearPileupDisplay') {
const { stateModel } = pluggableElement
const newStateModel = stateModel.extend(self => {
const superContextMenuItems = self.contextMenuItems
return {
views: {
contextMenuItems() {
const feature = self.contextMenuFeature
if (!feature) {
// we're not adding any menu items since the click was not
// on a feature
return superContextMenuItems()
}
return [
...superContextMenuItems(),
{
label: 'Some menu item',
icon: SomeIcon,
onClick: () => {
// do some stuff
},
},
]
},
},
}
})

pluggableElement.stateModel = newStateModel
}
return pluggableElement
},
)
}
}

Creating adapters

What is an adapter

An adapter is essentially a class that fetches and parses your data and returns it in a format JBrowse understands.

For example, if you have some data source that contains genes, and you want to display those genes using JBrowse's existing gene displays, you can write a custom adapter to do so. If you want to do a custom display of your data, though, you'll probably need to create a custom display and/or renderer along with your adapter.

What types of adapters are there

  • Feature adapter - This is the most common type of adapter. Essentially, it takes a request for a region (a chromosome, starting position, and ending position) and returns the features (e.g. genes, reads, variants, etc.) that are in that region. Examples of this in JBrowse include adapters for BAM and VCF file formats.
  • Regions adapter - This type of adapter is used to define what regions are in an assembly. It returns a list of chromosomes/contigs/scaffolds and their sizes. An example of this in JBrowse is an adapter for a chrome.sizes file.
  • Sequence adapter - This is basically a combination of a regions adapter and a feature adapter. It can give the list of regions in an assembly, and can also return the sequence of a queried region. Examples of this in JBrowse include adapters for FASTA and .2bit file formats.
  • RefName alias adapter - This type of adapter is used to return data about aliases for reference sequence names, for example to define that "chr1" is an alias for "1". An example of this in JBrowse is an adapter for (alias files)[http://software.broadinstitute.org/software/igv/LoadData/#aliasfile]
  • Text search adapter - This type of adapter is used to search through text search indexes. Returns list of search results. An example of this in JBrowse is the trix text search adapter.
Note

When using the refName alias adapter, it's important that the first column match what is seen in your FASTA file.

Skeleton of a feature adapter

A basic feature adapter might look like this (with implementation omitted for simplicity):

class MyAdapter extends BaseFeatureDataAdapter {
constructor(config) {
// config
}
async getRefNames() {
// return refNames used in your adapter, used for refName renaming
}

getFeatures(region, opts) {
// region: {
// refName:string, e.g. chr1
// start:number, 0-based half open start coord
// end:number, 0-based half open end coord
// assemblyName:string, assembly name
// originalRefName:string the name of the refName from the fasta file, e.g. 1 instead of chr1
// }
// opts: {
// signal?: AbortSignal
// ...rest: all the renderProps() object from the display type
// }
}

freeResources(region) {
// can be empty
}
}

So to make a feature adapter, you implement the getRefNames function (optional), the getFeatures function (returns an rxjs observable stream of features, discussed below) and freeResources (optional).

Example feature adapter

To take this a little slow, let's look at each function individually.

This is a more complete description of the class interface that you can implement:

import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter'
import SimpleFeature from '@jbrowse/core/util/simpleFeature'
import { readConfObject } from '@jbrowse/core/configuration'
import { ObservableCreate } from '@jbrowse/core/util/rxjs'

class MyAdapter extends BaseFeatureDataAdapter {
// your constructor gets a config object that you can read with readConfObject
// if you use "subadapters" then you can initialize those with getSubAdapter
constructor(config, getSubAdapter) {
const fileLocation = readConfObject(config, 'fileLocation')
const subadapter = readConfObject(config, 'sequenceAdapter')
const sequenceAdapter = getSubAdapter(subadapter)
}

// use rxjs observer.next(new SimpleFeature(...your feature data....) for each
// feature you want to return
getFeatures(region, options) {
return ObservableCreate(async observer => {
try {
const { refName, start, end } = region
const response = await fetch(
'http://myservice/genes/${refName}/${start}-${end}',
options,
)
if (response.ok) {
const features = await result.json()
features.forEach(feature => {
observer.next(
new SimpleFeature({
uniqueID: `${feature.refName}-${feature.start}-${feature.end}`,
refName: feature.refName,
start: feature.start,
end: feature.end,
}),
)
})
observer.complete()
} else {
throw new Error(`${response.status} - ${response.statusText}`)
}
} catch (e) {
observer.error(e)
}
})
}

async getRefNames() {
// returns the list of refseq names in the file, used for refseq renaming
// you can hardcode this if you know it ahead of time e.g. for your own
// remote data API or fetch this from your data file e.g. from the bam header
return ['chr1', 'chr2', 'chr3'] /// etc
}

freeResources(region) {
// optionally remove cache resources for a region
// can just be an empty function
}
}

What is needed from a feature adapter

getRefNames

Returns the refNames that are contained in the file. This is used for "refname renaming" and is optional, but highly useful in scenarios like human chromosomes which have, for example, chr1 vs 1.

Returning the refNames used by a given file or resource allows JBrowse to automatically smooth these small naming disparities over. See reference renaming.

getFeatures

A function that returns features from the file given a genomic range query e.g.,

getFeatures(region, options)

The region parameter contains:

interface Region {
refName: string
start: number
end: number
originalRefName: string
assemblyName: string
}

The refName, start, end specify a simple genomic range. The assemblyName is used to query a specific assembly if your adapter responds to multiple assemblies, e.g. for a synteny data file or a REST API that queries a backend with multiple assemblies.

The originalRefName are also passed, where originalRefName is the queried refname before ref renaming e.g. in BamAdapter, if the BAM file uses chr1, and your reference genome file uses 1, then originalRefName will be 1 and refName will be chr1.

The options parameter to getFeatures can contain any number of things:

interface Options {
bpPerPx: number
signal: AbortSignal
statusCallback: Function
headers: Record<string, string>
}
  • bpPerPx - number: resolution of the genome browser when the features were fetched
  • signal - can be used to abort a fetch request when it is no longer needed, from AbortController
  • statusCallback - not implemented yet but in the future may allow you to report the status of your loading operations
  • headers - set of HTTP headers as a JSON object

We return an rxjs Observable from getFeatures. This is similar to a JBrowse 1 getFeatures call, where we pass each feature to a featureCallback, tell it when we are done with finishCallback, and send errors to errorCallback, except we do all those things with the Observable

Here is a "conversion" of JBrowse 1 getFeatures callbacks to JBrowse 2 observable calls

  • featureCallback(new SimpleFeature(...)) -> observer.next(new SimpleFeature(...))
  • finishCallback() -> observer.complete()
  • errorCallback(error) -> observer.error(error)
freeResources

This is uncommonly used, so most adapters make this an empty function

Most adapters in fact use an LRU cache to make resources go away over time instead of manually cleaning up resources

Creating custom renderers

What is a renderer

In JBrowse 1, a track type typically would directly call the data parser and do it's own rendering. In JBrowse 2, the data parsing and rendering is offloaded to a web-worker or other RPC. This allows things to be faster in many cases. This is conceptually related to "server side rendering" or SSR in React terms.

Conceptual diagram of how a track calls a renderer using the RPC
Figure: Conceptual diagram of how a track calls a renderer using the RPC
Note

You can make custom track types that do not use this workflow, but it is a built-in workflow that functions well for the core track types in JBrowse 2, and is recommended.

How to create a new renderer

The fundamental aspect of creating a new renderer is creating a class that implements the "render" function. A renderer is actually a pair of a React component that contains the renderer's output, which we call the "rendering", and the renderer itself.

class MyRenderer implements ServerSideRendererType {
render(props) {
const { width, height, regions, features } = props
const canvas = createCanvas(width, height)
const ctx = canvas.getContext('2d')
ctx.fillStyle = 'red'
ctx.drawRect(0, 0, 100, 100)
const imageData = createImageBitmap(canvas)
return {
reactElement: React.createElement(this.ReactComponent, { ...props }),
imageData,
height,
width,
}
}
}

In the above simplified example, our renderer creates a canvas using width and height that are supplied via arguments, and draw a rectangle. We then return a React.createElement call which creates a "rendering" component that will contain the output.

Note

The above canvas operations use an OffscreenCanvas for Chrome, or in other browsers serialize the drawing commands to be drawn in the main thread.

What are the props passed to the renderer

The typical props that a renderer receives:

export interface PileupRenderProps {
features: Map<string, Feature>
layout: { addRect: (featureId, leftBp, rightBp, height) => number }
config: AnyConfigurationModel
regions: Region[]
bpPerPx: number
height: number
width: number
highResolutionScaling: number
}

The layout is available on BoxRendererType renderers so that it can layout things in pileup format, and has an addRect function to get the y-coordinate at which to render your data.

The features argument is a map of feature ID to the feature itself. To iterate over the features Map, we can use an iterator or convert to an array:

class MyRenderer extends ServerSideRendererType {
render(props) {
const { features, width, height } = props
// iterate over the ES6 map of features
for (const feature in features.values()) {
// render each feature to canvas or output SVG
}

// alternatively
const feats = Array.from(features.values())
feats.forEach(feat => {})
}
}

Adding custom props to the renderer

Track models themselves can extend this using their renderProps function.

For example, the WiggleTrack has code similar to this, which adds a scaleOpts prop that gets passed to the renderer:

const model = types
.compose(
'WiggleTrack',
blockBasedTrack,
types.model({
type: types.literal('WiggleTrack'),
}),
)
.views(self => {
const { renderProps: superRenderProps } = self
return {
renderProps() {
return {
...superRenderProps(),
scaleOpts: {
domain: this.domain,
stats: self.stats,
autoscaleType: getConf(self, 'autoscale'),
scaleType: getConf(self, 'scaleType'),
inverted: getConf(self, 'inverted'),
},
}
},
}
})

Rendering SVG

Our SVG renderer is an example, where it extends the existing built in renderer type with a custom ReactComponent only:

export default class SVGPlugin extends Plugin {
install(pluginManager: PluginManager) {
pluginManager.addRendererType(
() =>
new BoxRendererType({
name: 'SvgFeatureRenderer',
ReactComponent: SvgFeatureRendererReactComponent,
configSchema: svgFeatureRendererConfigSchema,
pluginManager,
}),
)
}
}

Then, we have our Rendering component just be plain React code. This is a highly simplified SVG renderer just to illustrate:

export default function SvgFeatureRendering(props) {
const { width, features, regions, layout, bpPerPx } = props
const region = regions[0]

const feats = Array.from(features.values())
const height = readConfObject(config, 'height', { feature })
return (
<svg>
{feats.map(feature => {
// our layout determines at what y-coordinate to
// plot our feature, given all the other features
const top = layout.addRect(
feature.id(),
feature.get('start'),
feature.get('end'),
height,
)
const [left, right] = bpSpanPx(
feature.get('start'),
feature.get('end'),
region,
bpPerPx,
)
return <rect x={left} y={top} height={height} width={right - left} />
})}
</svg>
)
}
Note

1.The above SVG renderer is highly simplified, but it shows that you can have a simple React component that leverages the existing BoxRendererType, so that you do not have to necessarily create your own renderer class

2.The renderers receive an array of regions to render, but if they are only equipped to handle one region at a time then they can select only rendering to regions[0]

Overriding the renderer's getFeatures method

Normally, it is sufficient to override the getFeatures function in your dataAdapter.

If you want to drastically modify the feature fetching behavior, you can modify the renderer's getFeatures call.

The base ServerSideRendererType class has a built-in getFeatures function that, in turn, calls your adapter's getFeatures function, but if you need tighter control over how your adapter's getFeatures method is called, then your renderer.

The Hi-C renderer type does not operate on conventional features and instead works with contact matrices, so the Hi-C renderer has a custom getFeatures function:

import { toArray } from 'rxjs/operators'
class HicRenderer extends ServerSideRendererType {
async getFeatures(args) {
const { dataAdapter, regions } = args
const features = await dataAdapter
.getFeatures(regions[0])
.pipe(toArray())
.toPromise()
return features
}
}

Creating custom track types

At a high level, the track types are just "ReactComponents" that contain rendered track contents. Oftentimes, for custom drawing, we create a renderer instead of a track, but here are some reasons you might want a custom track:

  • Drawing custom things over the rendered content (e.g. drawing the Y-scale bar in the wiggle track)
  • Implementing custom track menu items (e.g. Show soft clipping in the alignments track)
  • Adding custom widgets (e.g. custom VariantFeatureWidget in variant track)
  • You want to bundle your renderer and adapter as a specific thing that is automatically initialized rather than the BasicTrack (which combines any adapter and renderer)

For examples of custom track types, refer to things like:

  • HicTrack, which uses a custom HicRenderer to draw contact matrix
  • GDCPlugin, which has a custom track type that registers custom feature detail widgets
  • VariantTrack, which also registers custom widgets, and has ChordVariantDisplay and LinearVariantDisplay
  • SyntenyTrack, which can be displayed with DotplotDisplay or LinearSyntenyDisplay

URL query parameter API

JBrowse Web features the ability to automatically provide URL parameters to setup a session

Note that the embedded components like @jbrowse/react-linear-genome-view make no assumptions on how URL params are used, so would have to be implemented by the consumer of the library

Simple API for linear genome view

We provide a simplified URL format specifically designed for launching a single linear genome view

Example

http://host/jbrowse2/?config=test_data/config.json&loc=chr1:6000-7000&assembly=hg19&tracks=gene_track,vcf_track

Here are the query params used here

?config=

Example

?config=test_data/volvox/config.json

A path to a JBrowse 2 config file, relative to the current folder on the disk. Note that this just uses client side fetch to read the file, not server side file reads. If ?config= is not specified, it looks for a file named config.json e.g. http://host/jbrowse2/config.json which is what the @jbrowse/cli tool sets up by default

&assembly=

Example

&assembly=hg19

The &assembly parameter refers to an assembly's "name" field one of the "assemblies" array in the from the config.json. This is only used for launching a single linear genome view.

&loc=

Example

&loc=chr1:6000-7000

This performs a navigation to this region on load, which can be specified using the syntax. This is only used for launching a single linear genome view.

Example strings

chr1:6000-7000 // using - notation for range
chr1:6000..7000 // using .. notation for range
chr1:7000 // centered on this position

Note: Navigating via a text search query e.g. supply &loc=gene_name is not yet supported

&tracks=

Example

&tracks=gene_track,vcf_track

This is a comma separated list of trackIds. You can see your trackId's in the config.json. Note, you can also refer to a trackId added by &sessionTracks= here. This is only used for launching a single linear genome view.

More URL parameters

&sessionTracks=

If you want to dynamically add a track to the session, you can do so with &sessionTracks=

You can also use this method to add a FromConfigAdapter track, which let's you specify features in JSON format, so you can e.g. add BLAST hits via the URL bar

Example

https://jbrowse.org/code/jb2/main/?config=test_data/volvox/config.json&loc=ctgA:1-800&assembly=volvox&tracks=gff3tabix_genes,volvox_filtered_vcf,volvox_microarray,volvox_cram,url_track&sessionTracks=[{"type":"FeatureTrack","trackId":"url_track","name":"URL track","assemblyNames":["volvox"],"adapter":{"type":"FromConfigAdapter","features":[{"uniqueId":"one","refName":"ctgA","start":100,"end":200,"name":"Boris"}]}}]

Live link

This creates a track dynamically that has a single feature at chr1:100-200

The data to supply to &sessionTracks= is an array of track configs, and in the above URL, looks like this when pretty-printed

[
{
"type": "FeatureTrack",
"trackId": "url_track",
"name": "URL track",
"assemblyNames": ["volvox"],
"adapter": {
"type": "FromConfigAdapter",
"features": [
{
"uniqueId": "one",
"refName": "ctgA",
"start": 190,
"end": 191,
"name": "Boris"
}
]
}
}
]

&session=

The session parameter, e.g. &session= has a number of different "input formats"

Local sessions

The local sessions look like this

https://host/jbrowse2/?session=local-Fjphq8kjY

By default, after a session is loaded, it is stored into localStorage, and then the URL bar uses the ?session=local- format to reflect the key of the localStorage entry.

Shared sessions

If you click the "Share button" in the header bar, it will generate a "shareable link" that you can give to other users

https://host/jbrowse2/?session=share-HShsEcnq3i&password=nYzTU

See this FAQ entry for more info about how shared sessions work

Session spec

Another useful session URL is called a "session spec" or "session specification". This provides a way to launch multiple views at once, including view types other than the linear genome view

Linear Genome View
https://jbrowse.org/code/jb2/main/?config=test_data/volvox/config.json&session=spec-{"views":[{"assembly":"volvox","loc":"ctgA:1-5100","type": "LinearGenomeView","tracks":["gff3tabix_genes","volvox_filtered_vcf","volvox_microarray","volvox_cram"]}]}

Live link

Expanded

{
"views": [
{
"assembly": "volvox",
"loc": "ctgA:1-5100",
"type": "LinearGenomeView",
"tracks": [
"gff3tabix_genes",
"volvox_filtered_vcf",
"volvox_microarray",
"volvox_cram"
]
}
]
}

As you can see, you can supply an array of views (so you can open multiple views at once) and can specify the loc, tracks, assembly, and view type, or other view specific parameters (different view types may accept different params, e.g. dotplot has two assemblies)

Circular view

Here is a session spec for a Circular View

https://jbrowse.org/code/jb2/main/?config=test_data/volvox/config.json&session=spec-{"views":[{"assembly":"volvox","loc":"ctgA:1-5100","type": "CircularView","tracks":["volvox_sv_test"]}]}

Live link

Expanded

{
"views": [
{
"assembly": "volvox",
"loc": "ctgA:1-5100",
"type": "CircularView",
"tracks": ["volvox_sv_test"]
}
]
}
Dotplot view
https://jbrowse.org/code/jb2/main/?config=test_data/volvox/config_main_thread.json&session=spec-%7B"views":%5B%7B"type":"DotplotView","views":%5B%7B"assembly":"volvox"%7D,%7B"assembly":"volvox"%7D%5D,"tracks":%5B"volvox_fake_synteny"%5D%7D%5D%7D

Live link

Expanded

{
"views": [
{
"type": "DotplotView",
"views": [{ "assembly": "volvox" }, { "assembly": "volvox" }],
"tracks": ["volvox_fake_synteny"]
}
]
}

Note that this dotplot session spec doesn't have the ability to navigate to specific regions on the assembly yet, it just navigates to a whole genome overview

Spreadsheet view
https://jbrowse.org/code/jb2/main/?config=test_data/volvox/config.json&session=spec-%7B%22views%22:%5B%7B%22type%22:%22SpreadsheetView%22,%20%22uri%22:%22test_data/volvox/volvox.filtered.vcf.gz%22,%22assembly%22:%22volvox%22%7D%5D%7D

Live link

Expanded

{
"views": [
{
"type": "SpreadsheetView",
"uri": "test_data/volvox/volvox.filtered.vcf.gz",
"assembly": "volvox"
}
]
}
SV inspector
https://jbrowse.org/code/jb2/main/?config=test_data/volvox/config.json&session=spec-%7B"views":%5B%7B"type":"SvInspectorView","uri":"test_data/volvox/volvox.dup.vcf.gz","assembly":"volvox"%7D%5D%7D

Live link

Expanded

{
views: [
{
type: "SvInspectorView",
uri: "test_data/volvox/volvox.dup.vcf.gz",
assembly: "volvox",
},
],
};
Linear synteny view
https://jbrowse.org/code/jb2/main/?config=test_data%2Fvolvox%2Fconfig.json&session=spec-{"views":[{"type":"LinearSyntenyView","tracks":["volvox_fake_synteny"],"views":[{"loc":"ctgA:1-100","assembly":"volvox"},{"loc":"ctgA:300-400","assembly":"volvox"}]}]}

Live link

Expanded

{
"views": [
{
"type": "LinearSyntenyView",
"tracks": ["volvox_fake_synteny"],
"views": [
{ "loc": "ctgA:1-100", "assembly": "volvox" },
{ "loc": "ctgA:300-400", "assembly": "volvox" }
]
}
]
}
JSON sessions

Similar to encoded sessions, but more readable, JSON session let you specify the input a JSON snapshot of a session session. This is slightly different from a session spec, which has extra logic that loads the session. JSON sessions are literal session snapshots, like those that might come from the "Export session..." process

Example

&session=json-{"session":{"id":"xSHu7qGJN","name":"test","sessionPlugins":[{"url":"https://unpkg.com/jbrowse-plugin-msaview/dist/jbrowse-plugin-msaview.umd.production.min.js"}]}}

This loads a session with an extra plugin loaded

Encoded sessions

This is similar to JSON sessions but uses a URL encoding (base64+gzip)

Example

https://jbrowse.org/code/jb2/v1.5.9/?session=encoded-eJyNU2FzmkAQ_SvOfaaNIKDyLbFN0xlrTWRqnU4mc8ACm8BB7k6NdfjvXcCiZpq23-Dt2923u-_2DCPmsevHMn0ePT2umMEEz4GgGWx7C1AKC9EzzQv7wupbpkGfntX3HKt3-YW4OZcJCub1DRZJvgW5xEinzBuMbINtELaKeT_2bY98E0ym_PvdR8rTu7LuMUUBXH4CUeTwjdgUKeJYgZ6_MM-yLWtsGiwo5yBrwBkO3w9dx3b7I3fsuI5FTVGVGd9BdAcJCW27SYhn7QxDKqg0l7pRCIJkmM7YHIxcd2AQbwNSAYExzxQYjCsFeZDtDtlpYo5ZdU9qJQ-fTiZxxrPVYGrf-sdJroHrtQS_ZhIaFiLGZC25JlUUFmGAD0kcPzQ1O90nNQe72dU0eC716vV6rrjC8EObQLEUMElpINu0_tHn3R_yq_t6oBQjuAEegexmP0JfaSv16bpQM_4CMgh1If1WWooguQxTDHnGDpQpDyCjkVhBFTJeliiS-gBpsZ2A0CBrPV3VBt7pIuAiUgvQumZ7Wq6hVrjFKAFNxfZnrfxTKXWw2d3bjG6VN29Rlk2j5mQZaW7ssK8MFmNGin14oVUz1pr5zMQVkXiocQPL_9L6l1jVHFLQD13xsyDHihBqb9AiVPsE_d8WPEKTLuUcv2xdjK8qzLM1PdUDlqPAHH-eeL99vvNC4cFKsrFZ9QuCGmjL

Note that the "Share" button has a gear icon that let's you select "Long URL" that produces these URLs. The encoded share links can be used without the central session sharing system in place, as the entire session is encoded in the URL.

API

This guide will cover the API level documentation for methods and tools useful to developers looking to enhance JBrowse or write plugins.

You can add menus or add items to existing menus in several places.

In these different places, a MenuItem object defines the menu item's text, icon, action, and other attributes.

Types of MenuItems:

  • Normal: a standard menu item that performs an action when clicked
  • Checkbox: a menu item that has a checkbox
  • Radio: a menu item that has a radio button icon
  • Divider: a horizontal line (not clickable) that can be used to visually divide menus
  • SubHeader: text (not clickable) that can be used to visually label a section of a menu
  • SubMenu: contains menu items, for making nested menus
NameDescription
typeOptions are 'normal', 'radio', 'checkbox', 'subMenu', 'subHeader', or 'divider'. If not provided, defaults to 'normal', unless a subMenu attribute is present, in which case it defaults to 'subMenu'.
labelThe text for the menu item. Not applicable to 'divider', required for all others.
subLabelAdditional descriptive text for the menu item. Not applicable to 'divider' or 'subHeader', optional for all others.
iconAn icon for the menu item. Must be compatible with Material-UI's Icons. Not applicable to 'divider' or 'subHeader', optional for all others.
disabledWhether or not the menu item is disabled (meaning grayed out and not clickable). Not applicable to 'divider' or 'subHeader', optional for all others.
checkedWhether or not the checkbox or radio button are selected. Only applicable to 'radio' and 'checkbox'
onClickCallback of action to perform on click. Function signature is (session) => undefined. Required for 'normal', 'radio', and 'checkbox', not applicable to any others.
subMenuAn array of menu items. Applicable only to 'subMenu'.

As an example, the here is an array of MenuItems and the resulting menu:

;[
{
label: 'Normal menu item',
icon: AddIcon,
onClick: () => {},
},
{
label: 'Normal',
subLabel: 'with subLabel',
icon: AddIcon,
onClick: () => {},
},
{
label: 'Disabled menu item',
disabled: true,
icon: AddIcon,
onClick: () => {},
},
{
type: 'radio',
label: 'Radio checked',
checked: true,
onClick: () => {},
},
{
type: 'radio',
label: 'Radio unchecked',
checked: false,
onClick: () => {},
},
{
type: 'checkbox',
label: 'Checkbox checked',
checked: true,
onClick: () => {},
},
{
type: 'checkbox',
label: 'Checkbox unchecked',
checked: false,
onClick: () => {},
},
{ type: 'divider' },
{ type: 'subHeader', label: 'This is a subHeader' },
{
label: 'SubMenu',
subMenu: [
{
label: 'SubMenu item one',
onClick: () => {},
},
{
label: 'SubMenu item two',
onClick: () => {},
},
],
},
]
This screenshot shows all the various track menu options, generated by the code listing
Figure: This screenshot shows all the various track menu options, generated by the code listing

rootModel Menu API

Users can customize the top-level menu items using these functions that are available on the rootModel:

appendMenu

Add a top-level menu

Parameters
NameDescription
menuNameName of the menu to insert.
Return Value

The new length of the top-level menus array

insertMenu

Insert a top-level menu

Parameters
NameDescription
menuNameName of the menu to insert.
positionPosition to insert menu. If negative, counts from the end, e.g. insertMenu('My Menu', -1) will insert the menu as the second-to-last one.
Return Value

The new length of the top-level menus array

appendToMenu

Add a menu item to a top-level menu

Parameters
NameDescription
menuNameName of the top-level menu to append to.
menuItemMenu item to append.
Return Value

The new length of the menu

insertInMenu

Insert a menu item into a top-level menu

Parameters
NameDescription
menuNameName of the top-level menu to insert into.
menuItemMenu item to insert.
positionPosition to insert menu item. If negative, counts from the end, e.g. insertMenu('My Menu', -1) will insert the menu as the second-to-last one.
Return Value

The new length of the menu

appendToSubMenu

Add a menu item to a sub-menu

Parameters
NameDescription
menuPathPath to the sub-menu to add to, starting with the top-level menu (e.g. ['File', 'Insert']).
menuItemMenu item to append.
Return value

The new length of the sub-menu

insertInSubMenu

Insert a menu item into a sub-menu

Parameters
NameDescription
menuPathPath to the sub-menu to add to, starting with the top-level menu (e.g. ['File', 'Insert']).
menuItemMenu item to insert.
positionPosition to insert menu item. If negative, counts from the end, e.g. insertMenu('My Menu', -1) will insert the menu as the second-to-last one.
Return value

The new length of the sub-menu

Extension points

In the core codebase, we have the concept of extension points that users can call or add to.

The API is

pluginManager.evaluateExtensionPoint(extensionPointName, args)

There is also an async method:

pluginManager.evaluateAsyncExtensionPoint(extensionPointName, args)

Users can additionally add to extension points, so that when they are evaluated, it runs a chain of callbacks that are registered to that extension point:

pluginManager.addToExtensionPoint(extensionPointName, callback => newArgs)

Here are the extension points in the core codebase:

Core-extendPluggableElement

(sync) used to add extra functionality to existing state tree models, for example, extra right-click context menus

Core-guessAdapterForLocation

(sync) used to infer an adapter type given a location type from the "Add track" workflow

Core-guessTrackTypeForLocation

(sync) used to infer a track type given a location type from the "Add track workflow"

TrackSelector-multiTrackMenuItems

(sync) used to add new menu items to the "shopping cart" in the header of the hierarchical track menu when tracks are added to the selection

LaunchView-LinearGenomeView

(async) launches a linear genome view given parameters

  • session:AbstractSessionModel - instance of the session which you can call actions on
  • assembly:string - assembly name
  • loc:string - a locstring
  • tracks:string[] - array of trackIds

LaunchView-CircularView

  • session:AbstractSessionModel - instance of the session which you can call actions on
  • assembly:string - assembly name
  • tracks:string[] - array of trackIds

Extension point footnote

Users that want to add further extension points can do so. The naming system, "Core-" just refers to the fact that these extension points are from our core codebase. Plugin developers may choose their own prefix to avoid collisions.

JBrowse Jupyter

Comprehensive documentation for JBrowse Jupyter is found off-site, here.

Also check out the JBrowse Jupyter Github repo.

Embedded components

Our embedded components allow you to use individual JBrowse views in your application

JBrowse React Linear Genome View

This component consists of a single JBrowse 2 linear view.

Here is a table of different usages of the @jbrowse/react-linear-genome-view using different bundlers

BundlerDemoSource codeNote
create-react-app v4demosource code (download)no polyfills needed in create-react-app v4
create-react-app v5demosource code (download)for create-react-app v5, we use craco to update the webpack config to polyfill some node modules
vitedemosource code (download)for vite, we use rollup to polyfill some node polyfills similar to craco in create-react-app v5. note, may not work with newly released vite 3.x, works in dev but fails in production so this example uses vite 2.x
next.jsdemosource code (download)uses next.js 12. Also see next.config.js to update basePath as needed
vanilla jsdemosource code (download)uses a script tag to include a UMD bundle, and doesn't require any transpilation or bundling. see also dev tutorial here https://jbrowse.org/jb2/docs/tutorials/embed_linear_genome_view/01_introduction/

JBrowse React Circular Genome View

This component consists of a single JBrowse 2 circular view.

Here is a table of different usages of the @jbrowse/react-circular-genome-view using different bundlers

SyntaxDemoSource codeNote
create-react-app v4demosource code (download)no polyfills needed in create-react-app v4
create-react-app v5demosource code (download)for create-react-app v5, we use craco to update the webpack config to polyfill some node modules
vanilla jsdemosource code (download)uses a script tag to include a UMD bundle, and doesn't require any transpilation or bundling

Command line tools

This document covers the CLI tools. Note: for @jbrowse/img static export tool, see https://www.npmjs.com/package/@jbrowse/img

Installation

The command line tools can be installed globally using npm as follows

$ npm install -g @jbrowse/cli

A CLI tool called jbrowse should then be available in the path. You can test your installation with

$ jbrowse --version

It is also possible to do one-off executions using npx, e.g.

npx @jbrowse/cli create myfolder

It is likely preferable in most cases to install the tools globally with npm install @jbrowse/cli -g however

Commands

jbrowse add-assembly SEQUENCE

Add an assembly to a JBrowse 2 configuration

USAGE
$ jbrowse add-assembly SEQUENCE

ARGUMENTS
SEQUENCE
sequence file or URL

If TYPE is indexedFasta or bgzipFasta, the index file defaults to <location>.fai
and can be optionally specified with --faiLocation
If TYPE is bgzipFasta, the gzip index file defaults to <location>.gzi and can be
optionally specified with --gziLocation

OPTIONS
-a, --alias=alias
An alias for the assembly name (e.g. "hg38" if the name of the assembly is "GRCh38");
can be specified multiple times

-f, --force
Equivalent to `--skipCheck --overwrite`

-h, --help
show CLI help

-l, --load=copy|symlink|move|inPlace
Required flag when using a local file. Choose how to manage the data directory. Copy, symlink, or move the data
directory to the JBrowse directory. Or use inPlace to modify the config without doing any file operations

-n, --name=name
Name of the assembly; if not specified, will be guessed using the sequence file name

-t, --type=indexedFasta|bgzipFasta|twoBit|chromSizes|custom
type of sequence, by default inferred from sequence file

indexedFasta An index FASTA (e.g. .fa or .fasta) file;
can optionally specify --faiLocation

bgzipFasta A block-gzipped and indexed FASTA (e.g. .fa.gz or .fasta.gz) file;
can optionally specify --faiLocation and/or --gziLocation

twoBit A twoBit (e.g. .2bit) file

chromSizes A chromosome sizes (e.g. .chrom.sizes) file

custom Either a JSON file location or inline JSON that defines a custom
sequence adapter; must provide --name if using inline JSON

--displayName=displayName
The display name to specify for the assembly, e.g. "Homo sapiens (hg38)" while the name can be a shorter identifier
like "hg38"

--faiLocation=faiLocation
[default: <fastaLocation>.fai] FASTA index file or URL

--gziLocation=gziLocation
[default: <fastaLocation>.gzi] FASTA gzip index file or URL

--out=out
synonym for target

--overwrite
Overwrite existing assembly if one with the same name exists

--refNameAliases=refNameAliases
Reference sequence name aliases file or URL; assumed to be a tab-separated aliases
file unless --refNameAliasesType is specified

--refNameAliasesType=aliases|custom
Type of aliases defined by --refNameAliases; if "custom", --refNameAliases is either
a JSON file location or inline JSON that defines a custom sequence adapter

--refNameColors=refNameColors
A comma-separated list of color strings for the reference sequence names; will cycle
through colors if there are fewer colors than sequences

--skipCheck
Don't check whether or not the sequence file or URL exists or if you are in a JBrowse directory

--target=target
path to config file in JB2 installation directory to write out to.
Creates ./config.json if nonexistent

EXAMPLES
# add assembly to installation in current directory. assumes .fai file also exists, and copies GRCh38.fa and
GRCh38.fa.fai to current directory
$ jbrowse add-assembly GRCh38.fa --load copy

# add assembly to a specific jb2 installation path using --out, and copies the .fa and .fa.fai file to /path/to/jb2
$ jbrowse add-assembly GRCh38.fa --out /path/to/jb2/ --load copy

# force indexedFasta for add-assembly without relying on file extension
$ jbrowse add-assembly GRCh38.xyz --type indexedFasta --load copy

# add displayName for an assembly
$ jbrowse add-assembly myFile.fa.gz --name hg38 --displayName "Homo sapiens (hg38)"

# use chrom.sizes file for assembly instead of a fasta file
$ jbrowse add-assembly GRCh38.chrom.sizes --load inPlace

# add assembly from preconfigured json file, expert option
$ jbrowse add-assembly GRCh38.config.json --load copy

# add assembly from a 2bit file, also note pointing direct to a URL so no --load flag needed
$ jbrowse add-assembly https://example.com/data/sample.2bit

# add a bgzip indexed fasta inferred by fa.gz extension. assumes .fa.gz.gzi and .fa.gz.fai files also exists
$ jbrowse add-assembly myfile.fa.gz --load copy

See code: src/commands/add-assembly.ts

jbrowse add-connection CONNECTIONURLORPATH

Add a connection to a JBrowse 2 configuration

USAGE
$ jbrowse add-connection CONNECTIONURLORPATH

ARGUMENTS
CONNECTIONURLORPATH URL of data directory
For hub file, usually called hub.txt
For JBrowse 1, location of JB1 data directory similar to http://mysite.com/jbrowse/data/

OPTIONS
-a, --assemblyName=assemblyName Assembly name of the connection If none, will default to the assembly in your config
file

-c, --config=config Any extra config settings to add to connection in JSON object format, such as
'{"uri":"url":"https://sample.com"}, "locationType": "UriLocation"}'

-f, --force Equivalent to `--skipCheck --overwrite`

-h, --help show CLI help

-n, --name=name Name of the connection. Defaults to connectionId if not provided

-t, --type=type type of connection, ex. JBrowse1Connection, UCSCTrackHubConnection, custom

--connectionId=connectionId Id for the connection that must be unique to JBrowse. Defaults to
'connectionType-assemblyName-currentTime'

--out=out synonym for target

--overwrite Overwrites any existing connections if same connection id

--skipCheck Don't check whether or not the data directory URL exists or if you are in a JBrowse
directory

--target=target path to config file in JB2 installation directory to write out to.

EXAMPLES
$ jbrowse add-connection http://mysite.com/jbrowse/data/
$ jbrowse add-connection http://mysite.com/jbrowse/custom_data_folder/ --type JBrowse1Connection
$ jbrowse add-connection http://mysite.com/path/to/hub.txt --assemblyName hg19
$ jbrowse add-connection http://mysite.com/path/to/custom_hub_name.txt --type UCSCTrackHubConnection --assemblyName
hg19
$ jbrowse add-connection http://mysite.com/path/to/custom --type custom --config
'{"uri":{"url":"https://mysite.com/path/to/custom"}, "locationType": "UriLocation"}' --assemblyName hg19
$ jbrowse add-connection https://mysite.com/path/to/hub.txt --connectionId newId --name newName --target
/path/to/jb2/installation/config.json

See code: src/commands/add-connection.ts

jbrowse add-track TRACK

Add a track to a JBrowse 2 configuration

USAGE
$ jbrowse add-track TRACK

ARGUMENTS
TRACK Track file or URL

OPTIONS
-a, --assemblyNames=assemblyNames Assembly name or names for track as comma separated string. If none, will
default to the assembly in your config file

-d, --description=description Optional description of the track

-f, --force Equivalent to `--skipCheck --overwrite`

-h, --help show CLI help

-l, --load=copy|symlink|move|inPlace Required flag when using a local file. Choose how to manage the track. Copy,
symlink, or move the track to the JBrowse directory. Or inPlace to leave track
alone

-n, --name=name Name of the track. Will be defaulted to the trackId if none specified

-t, --trackType=trackType Type of track, by default inferred from track file

--category=category Optional Comma separated string of categories to group tracks

--config=config Any extra config settings to add to a track. i.e '{"defaultRendering":
"density"}'

--indexFile=indexFile Optional index file for the track

--out=out synonym for target

--overwrite Overwrites existing track if it shares the same trackId

--protocol=protocol [default: uri] Force protocol to a specific value

--skipCheck Skip check for whether or not the file or URL exists or if you are in a JBrowse
directory

--subDir=subDir when using --load a file, output to a subdirectory of the target dir

--target=target path to config file in JB2 installation to write out to.

--trackId=trackId trackId for the track, by default inferred from filename, must be unique
throughout config

EXAMPLES
# copy /path/to/my.bam and /path/to/my.bam.bai to current directory and adds track to config.json
$ jbrowse add-track /path/to/my.bam --load copy

# copy my.bam and my.bam.bai to /path/to/jb2/bam and adds track entry to /path/to/jb2/bam/config.json
$ jbrowse add-track my.bam --load copy --out /path/to/jb2 --subDir bam

# same as above, but specify path to bai file. needed for if the bai file does not have the extension .bam.bai
$ jbrowse add-track my.bam --indexFile my.bai --load copy

# creates symlink for /path/to/my.bam and adds track to config.json
$ jbrowse add-track /path/to/my.bam --load symlink

# add track from URL to config.json, no --load flag needed
$ jbrowse add-track https://mywebsite.com/my.bam

# --load inPlace adds a track without doing file operations
$ jbrowse add-track /url/relative/path.bam --load inPlace

See code: src/commands/add-track.ts

jbrowse add-track-json TRACK

Add a track configuration directly from a JSON hunk to the JBrowse 2 configuration

USAGE
$ jbrowse add-track-json TRACK

ARGUMENTS
TRACK track JSON file or command line arg blob

OPTIONS
-u, --update update the contents of an existing track, matched based on trackId
--out=out synonym for target

--target=target path to config file in JB2 installation directory to write out to.
Creates ./config.json if nonexistent

EXAMPLES
$ jbrowse add-track-json track.json
$ jbrowse add-track-json track.json --update

See code: src/commands/add-track-json.ts

jbrowse admin-server

Start up a small admin server for JBrowse configuration

USAGE
$ jbrowse admin-server

OPTIONS
-h, --help show CLI help

-p, --port=port Specifified port to start the server on;
Default is 9090.

--bodySizeLimit=bodySizeLimit [default: 25mb] Size limit of the update message; may need to increase if config is
large.
Argument is passed to bytes library for parsing: https://www.npmjs.com/package/bytes.

--root=root path to the root of the JB2 installation.
Creates ./config.json if nonexistent. note that you can navigate to
?config=path/to/subconfig.json in the web browser and it will write to
rootDir/path/to/subconfig.json

EXAMPLES
$ jbrowse admin-server
$ jbrowse admin-server -p 8888

See code: src/commands/admin-server.ts

jbrowse create LOCALPATH

Downloads and installs the latest JBrowse 2 release

USAGE
$ jbrowse create LOCALPATH

ARGUMENTS
LOCALPATH Location where JBrowse 2 will be installed

OPTIONS
-f, --force Overwrites existing JBrowse 2 installation if present in path
-h, --help show CLI help
-l, --listVersions Lists out all versions of JBrowse 2

-t, --tag=tag Version of JBrowse 2 to install. Format is v1.0.0.
Defaults to latest

-u, --url=url A direct URL to a JBrowse 2 release

--branch=branch Download a development build from a named git branch

--nightly Download the latest development build from the main branch

EXAMPLES
# Download latest release from github, and put in specific path
$ jbrowse create /path/to/new/installation

# Download latest release from github and force overwrite existing contents at path
$ jbrowse create /path/to/new/installation --force

# Download latest release from a specific URL
$ jbrowse create /path/to/new/installation --url url.com/directjbrowselink.zip

# Download a specific tag from github
$ jbrowse create /path/to/new/installation --tag v1.0.0

# List available versions
$ jbrowse create --listVersions

See code: src/commands/create.ts

jbrowse help [COMMAND]

display help for jbrowse

USAGE
$ jbrowse help [COMMAND]

ARGUMENTS
COMMAND command to show help for

OPTIONS
--all see all commands in CLI

See code: @oclif/plugin-help

jbrowse set-default-session

Set a default session with views and tracks

USAGE
$ jbrowse set-default-session

OPTIONS
-c, --currentSession List out the current default session
-h, --help show CLI help
-n, --name=name [default: New Default Session] Give a name for the default session
-s, --session=session set path to a file containing session in json format
-t, --tracks=tracks Track id or track ids as comma separated string to put into default session

-v, --view=view View type in config to be added as default session, i.e LinearGenomeView, CircularView,
DotplotView.
Must be provided if no default session file provided

--delete Delete any existing default session.

--out=out synonym for target

--target=target path to config file in JB2 installation directory to write out to

--viewId=viewId Identifier for the view. Will be generated on default

EXAMPLES
$ jbrowse set-default-session --session /path/to/default/session.json
$ jbrowse set-default-session --target /path/to/jb2/installation/config.json --view LinearGenomeView --tracks track1,
track2, track3
$ jbrowse set-default-session --view LinearGenomeView, --name newName --viewId view-no-tracks
$ jbrowse set-default-session --currentSession # Prints out current default session

See code: src/commands/set-default-session.ts

jbrowse text-index

Make a text-indexing file for any given track(s).

USAGE
$ jbrowse text-index

OPTIONS
-a, --assemblies=assemblies Specify the assembl(ies) to create an index for. If unspecified, creates an index for
each assembly in the config

-h, --help show CLI help

-q, --quiet Hide the progress bars

--attributes=attributes [default: Name,ID] Comma separated list of attributes to index

--dryrun Just print out tracks that will be indexed by the process, without doing any indexing

--exclude=exclude [default: CDS,exon] Adds gene type to list of excluded types

--file=file File or files to index (can be used to create trix indexes for embedded component use
cases not using a config.json for example)

--fileId=fileId Set the trackId used for the indexes generated with the --file argument

--force Overwrite previously existing indexes

--out=out Synonym for target

--perTrack If set, creates an index per track

--prefixSize=prefixSize [default: 6] Specify the prefix size for the ixx index, increase size if many of your
gene IDs have same prefix e.g. Z000000001, Z000000002

--target=target Path to config file in JB2 installation directory to read from.

--tracks=tracks Specific tracks to index, formatted as comma separated trackIds. If unspecified, indexes
all available tracks

EXAMPLES
# indexes all tracks that it can find in the current directory's config.json
$ jbrowse text-index

# indexes specific trackIds that it can find in the current directory's config.json
$ jbrowse text-index --tracks=track1,track2,track3

# indexes all tracks in a directory's config.json or in a specific config file
$ jbrowse text-index --out /path/to/jb2/

# indexes only a specific assembly, and overwrite what was previously there using force (which is needed if a previous
index already existed)
$ jbrowse text-index -a hg19 --force

# create index for some files for use in @jbrowse/react-linear-genome-view or similar
$ jbrowse text-index --file myfile.gff3.gz --file myfile.vcfgz --out indexes

See code: src/commands/text-index.ts

jbrowse upgrade [LOCALPATH]

Upgrades JBrowse 2 to latest version

USAGE
$ jbrowse upgrade [LOCALPATH]

ARGUMENTS
LOCALPATH [default: .] Location where JBrowse 2 is installed

OPTIONS
-h, --help show CLI help
-l, --listVersions Lists out all versions of JBrowse 2

-t, --tag=tag Version of JBrowse 2 to install. Format is v1.0.0.
Defaults to latest

-u, --url=url A direct URL to a JBrowse 2 release

--branch=branch Download a development build from a named git branch

--clean Removes old js,map,and LICENSE files in the installation

--nightly Download the latest development build from the main branch

EXAMPLES
# Upgrades current directory to latest jbrowse release
$ jbrowse upgrade

# Upgrade jbrowse instance at a specific filesystem path
$ jbrowse upgrade /path/to/jbrowse2/installation

# Upgrade to a specific tag
$ jbrowse upgrade /path/to/jbrowse2/installation --tag v1.0.0

# List versions available on github
$ jbrowse upgrade --listVersions

# Upgrade from a specific URL
$ jbrowse upgrade --url https://sample.com/jbrowse2.zip

# Get nightly release from main branch
$ jbrowse upgrade --nightly

See code: src/commands/upgrade.ts

Debugging

Debug logs (provided by debug) can be printed by setting the DEBUG environment variable. Setting DEBUG=* will print all debug logs. Setting DEBUG=jbrowse* will print only logs from this tool, and setting e.g. DEBUG=jbrowse:add-assembly will print only logs from the add-assembly command.

FAQ

Developers

How can I start the JBrowse 2 app as a developer

We recommend that you have the following:

  • A stable and recent version of node
  • Git
  • Yarn

Then you can follow steps from our README.

It basically boils down to:

git clone https://github.com/GMOD/jbrowse-components
cd jbrowse-components
yarn
cd products/jbrowse-web
yarn start

This will boot up a development instance of jbrowse-web on port 3000.

You can use PORT=8080 yarn start to manually specify a different port.

You can also instead go to the products/jbrowse-desktop directory to do this on desktop.

For the embedded components e.g. products/jbrowse-react-linear-genome-view, use yarn storybook instead of yarn start.

For a more extensive tutorial, see Developing with JBrowse web and desktop.

General

What is special about JBrowse 2

One thing that makes JBrowse 2 special is that we can create new view types via our plugin system, e.g. circular, dotplot, etc.. Anything you want can be added as a view, and can be shown alongside our other views.

This makes JBrowse 2 more than just a genome browser: it is really a platform that can be built upon.

What are new features in JBrowse 2

See the https://jbrowse.org/jb2/features page for an overview of features

Setup

What web server do I need to run JBrowse 2

JBrowse 2 by itself is just a set of JS, CSS, and HTML files that can be statically hosted on a webserver without any backend services running.

Therefore, running JBrowse 2 generally involves just copying the JBrowse 2 folder to your web server html folder e.g. copy /var/www/html/ to Amazon S3.

If you use a different platform such as Django, you may want to put it in the static resources folder.

Note that the server that you use should support byte-range requests (e.g. the Range HTTP header so that JBrowse can get small slices of large binary data files.

BAM files do not work on my server

If you are using Apache then you will probably want to disable mime_magic. If mime_magic is enabled, you may see that your server responds with the HTTP header Content-Encoding: gzip which JBrowse does NOT want, because this instructs the browser to unzip the data but JBrowse should be in charge of this.

How can I setup JBrowse 2 on my web server

We recommend following the steps in the quickstart web via CLI guide.

The general procedure is using the jbrowse create /var/www/html/jb2 and this will download the latest version of jbrowse to your web folder e.g. in /var/www/html.

You can also use jbrowse upgrade /var/www/html/jb2 to get the latest version.

How do I install or update the @jbrowse/cli tool

To install the @jbrowse/cli tool, you can use npm install -g @jbrowse/cli

You can use this same command to upgrade the tool too.

This command will give you a command named jbrowse which should automatically be in your path if you have a standard installation of nodejs. We recommend using nodesource or nvm to get your nodejs for this.

Also note that the @jbrowse/cli tool is just made for preparing your config.json, it is not used to run any server-side code.

How do I update my instance of jbrowse-web

You can use the command, after installing:

jbrowse upgrade /path/to/your/jbrowse2

This will download the latest release from github and overwrite it onto your jbrowse-web instance.

If you've manually downloaded jbrowse-web, the newest releases can be found here.

How can I setup JBrowse 2 without the CLI tools

The jbrowse CLI tools are basically a convenience, and are not strictly required.

Simple tasks can be done without it.

For example, for jbrowse create, you can visit the releases page and download the latest jbrowse-web release tag, and unzip it into your web directory.

Checkout our quickstart web guide for a speedy start to using a manually downloaded JBrowse instance.

For other things, like add-assembly and add-track, you can manually edit the config.json; reviewing the config docs and sample configs will be valuable.

To configure JBrowse using the GUI, checkout our tutorial.

Understanding the config basics will come in handy also because you can manually edit in advanced configs after your tracks are loaded; however be careful:s corrupt configs can produce hard to understand errors, because our config system is strongly typed.

Reach out to the team on gitter or in the discussions if you have any complex configuration issues.

How do I load a track into JBrowse 2

With the JBrowse CLI tools, you can easily add tracks with the add-track command, e.g.:

jbrowse add-track myfile.bw -a hg19

This will setup a bigwig track on the hg19 assembly in your config.json.

Make sure to run the command inside your current jbrowse2 folder e.g. /var/www/html/jbrowse2 or wherever you are currently setting up a config.json (you can have multiple configs).

Note that you can also use remote URLs

jbrowse add-track http://yourremote/myfile.bam

The add-track command will do as much as possible to infer from the file extension how to configure this track, and automatically infer the index to be myfile.bam.bai.

As mentioned above you can also manually edit your config file, or use the GUI.

How do I customize the color of the features displayed on my track

We use Jexl for defining configuration callbacks, including feature coloration.

An example of a Jexl configuration callback might look like this:

"color": "jexl:get(feature,'strand')==-1?'red':'blue'"

See our configuration callbacks guide for more information.

Adding color callbacks in the GUI

In brief, to add a configuration callback to a track using the GUI, perform the following steps:

  1. On the track you're meaning to color, click on the three vertical dots '...' on the right side of the track label
  2. Click "Settings" (if this option is greyed out, copy the track with "Copy Track", then open up the track under "Session Tracks" and repeat steps 1-2)
  3. Scroll down to the "display 1 renderer" heading (this is typically the display you want to edit, if not scroll to display 2)
  4. Click on the circle to the right of the color you'd like to change
  5. In this text box, enter in the Jexl callback for the feature colouration, e.g. "get(feature,'strand') == -1 ? 'red' : 'blue'"
Adding color callbacks via the command line

Adding color callbacks via the command line can be a little tricky because the coloration property exists within the renderer.

In brief, to add a configuration callback to a track using the CLI, your add-track is going to look something like this:

jbrowse add-track somevariants.vcf --load copy --config '{"displays": [{"displayId": "my_BasicDisplay", "type": "LinearBasicDisplay", "renderer": {"color1": "jexl:get(feature, 'strand') == -1 ? 'red' : 'blue'" }}]}'

While adding the track to the config.json, you're adding additional configurations using the --config option. This additional configuration is a "renderer" on the display that your track will be using. In this case, this .vcf will be using the LinearBasicDisplay

Curiosities

Why do all the tracks need an assembly specified

We require that all tracks have a specific genome assembly specified in their config. This is because JBrowse 2 is a multi-genome-assembly browser (and can compare genomes given the data). This may be different to using, say, JBrowse 1 where it knows which genome assembly you are working with at any given time.

How are the menus structured in the app

In JBrowse 1, the app level menu operated on the single linear genome view, but with JBrowse 2, the top level menu only performs global operations and the linear genome view has its own hamburger menu. Note that each track also has its own track level menu.

Why do some of my reads not display soft clipping

Some reads, such as secondary reads, do not have a SEQ field on their records, so they will not display softclipping.

The soft clipping indicators on these reads will appear black.

Do you have any tips for learning React and mobx-state-tree

Here is a short guide to React and mobx-state-tree that could help get you oriented:

https://gist.github.com/cmdcolin/94d1cbc285e6319cc3af4b9a8556f03f

What technologies does JBrowse 2 use

We build on a lot of great open source technology, some main ones include:

  • React
  • mobx-state-tree
  • web-workers
  • Typescript
  • Electron (for desktop specifically)
Should I configure gzip on my web server

Yes! JBrowse 2 may load ~5MB of JS resources (2.5MB for main thread bundle, 2.5MB for worker bundle). If you have gzip enabled, the amount of data the user has to download though is only 1.4MB. We have worked on making bundle size small with lazy loading and other methods but adding gzip will help your users.

It will depend on your particular server setup e.g. apache, nginx, cloudfront, etc. how this may be done, but it is recommended to look into this.

How does JBrowse know when to display the "Zoom in to see more features" message

The rules that JBrowse uses to determine when to display the "Zoom in to see more features" message are called stats estimation rules

The general outline is:

  • It doesn't display a zoom in message if zoomed in closer than 20kb
  • It performs byte size estimation for BAM and CRAM type files (you will see a byte size estimation displayed alongside the "Zoom in to see features" message
  • Other data types that don't use byte size estimation use feature density based calculation
  • Hi-C, BigWig, and sequence adapters are hardcoded to return { featureDensity:0 } to always render

If you need to customize your particular track, you can set config variables on the "display" section of your config

  • maxFeatureScreenDensity - number of features times bpPerPx
  • fetchSizeLimit - this config variable exists on the adapters (can increase size limit)

Example config with a small feature screen density:

{
"type": "VariantTrack",
"trackId": "variant_density",
"name": "test variants (small featuredensity limit)",
"assemblyNames": ["volvox"],
"adapter": {
"type": "VcfTabixAdapter",
"vcfGzLocation": {
"uri": "volvox.filtered.vcf.gz"
},
"index": {
"location": {
"uri": "volvox.filtered.vcf.gz.tbi"
}
}
},
"displays": [
{
"type": "LinearVariantDisplay",
"maxFeatureScreenDensity": 0.0006,
"displayId": "volvox_filtered_vcf_color-LinearVariantDisplay"
}
]
}

Example config for a CRAM file with a small fetchSizeLimit configured:

{
"type": "AlignmentsTrack",
"trackId": "volvox_cram",
"name": "test track (small fetch size limit)",
"assemblyNames": ["volvox"],
"adapter": {
"type": "CramAdapter",
"cramLocation": {
"uri": "volvox-sorted-altname.cram"
},
"craiLocation": {
"uri": "volvox-sorted-altname.cram.crai"
},
"sequenceAdapter": {
"type": "TwoBitAdapter",
"twoBitLocation": {
"uri": "volvox.2bit"
}
},
"fetchSizeLimit": 1000
}
}

Text searching

Why I am running out of disk space while trix is running

The jbrowse text-index program will output data to a TMP directory while indexing. If your filesystem has low diskspace for /tmp you can set an alternative temporary directory using the environment variable TMPDIR=~/alt_tmp_dir/ jbrowse text-index.

How does the jbrowse text-index trix format work

The jbrowse text-index command creates text searching indexes using trix. The trix indexes are based on the format described by UCSC here https://genome.ucsc.edu/goldenPath/help/trix.html, but we re-implemented the code the create these index formats in the JBrowse CLI so you do not have to install the UCSC tools.

The main idea is that you give trix:

GENEID001  Wnt signalling
GENEID002 ey Pax6

Then this will generate a new file, the .ix file, sorted in alphabetical order:

ey  GENE002
signalling GENE001
Pax6 GENE002
Wnt GENE001

Then a second file, the .ixx file, tells us at what byte offset certain lines in the file are e.g.:

signa000000435

Note that JBrowse creates a specialized trix index also. Instead of creating a ix file with just the gene names, it also provides their name and location in an encoded format.

URL params

Why can't I copy and paste my URL bar to share it with another user

In JBrowse Web, the current session can become too long to store in the URL bar, so instead, we store it in localStorage and only keep the key to the localStorage entry in the URL var. This is because otherwise URLs can get prohibitively long, and break server side navigations, intermediate caches, etc. Therefore, we make "sharing a session" a manual step that generates a shortened URL by default.

Note 1: users of @jbrowse/react-linear-genome-view have to re-implement any URL query param logic themselves, as this component makes no attempt to access URL query params.

Note 2: You can copy and paste your URL bar and put it in another tab on your own computer, and JBrowse will restore the session using BroadcastChannel (supported on Firefox and Chrome).

How does the session sharing work with shortened URLs work in JBrowse Web

We have a central database hosted as a AWS dynamoDB that stores encrypted session snapshots that users create when they use the "Share" button. The "Share" button creates a random key on the client side (which becomes the &password= component of the share URL), encrypts the session client side, and sends the encrypted session without the key to the AWS dynamoDB.

This process, generates a URL with the format:

&session=share-<DYNAMODBID>&password=<DECODEKEY>

The DECODEKEY is never transmitted to the server, but you can copy and paste the share URL, the person you shared automatically downloads the DynamoDB entry, and decodes it with the DECODEKEY from the URL that you provide

With this system, the contents of the dynamoDB are safe and unable to be read, even by JBrowse administrators.

Troubleshooting

Doing things like:

  • Changing trackIds
  • Deleting tracks

Can make user's saved sessions fail to load. If part of a session is inconsistent, currently, the entire session will fail to load. Therefore, make decisions to delete or change IDs carefully.

What should I do if the Share system isn't working?

If for any reason the session sharing system isn't working, e.g. you are behind a firewall or you are not able to connect to the central share server, you can click the "Gear" icon in the "Share" button pop-up, and it will give you the option to use "Long URL" instead of "Short URL" which let's you create share links without the central server.

Also, if you are implementing JBrowse Web on your own server and would like to create your own URL shortener, you can use the shareURL parameter in the config.json file to point at your own server instead of ours.