JBrowse 2 · React App examples

Synteny via the imperative mount

Mount the full app with createApp() — the framework-agnostic primitive non-React hosts (anywidget, htmlwidgets) use — and open a synteny view declaratively.

Everything else on this site drives the <JBrowse> React component. @jbrowse/embedded-app exposes the same engine a different way: createApp(element, options) — a framework-agnostic imperative mount with no React in its signature. It’s the multi-view counterpart to @jbrowse/embedded-linear-genome-view’s createLinearGenomeView, and the primitive that non-React hosts (Jupyter anywidgets, R htmlwidgets, plain <script> pages) wrap.

Because it drives the full app, one declarative views list reaches every view type — here a LinearSyntenyView, the exact same { type, init } shape the <JBrowse> synteny example uses:

import { createApp } from '@jbrowse/embedded-app'

const controller = createApp(document.getElementById('root'), {
  assemblies,
  tracks,
  views: [
    {
      type: 'LinearSyntenyView',
      init: {
        views: [{ assembly: 'volvox' }, { assembly: 'volvox_del' }],
        tracks: ['volvox_del.paf'],
      },
    },
  ],
})

// later: controller.addView({ type: 'DotplotView', init: {...} })
// on teardown: controller.destroy()

The init field is the same vocabulary JBrowse Web serializes into its ?session=spec-… URLs, so anything expressible there — synteny, dotplot, circular, breakpoint-split — is one entry in views.

Live demo

View source
import { createApp } from '@jbrowse/embedded-app'

import { volvoxConfig } from '../volvoxConfig.ts'

// Every other example on this site uses the <JBrowse> React component. This one
// uses `createApp` instead — the framework-agnostic imperative mount that
// non-React hosts (anywidget, R htmlwidgets, vanilla JS) wrap. It takes the same
// declarative `views` list, so a synteny view is one `{ type, init }` entry. A
// cleanup-returning ref bridges the imperative mount into React: it builds the
// app when the div attaches and disposes it when the div unmounts.
export default function EmbeddedAppSynteny() {
  return (
    <div
      ref={el => {
        if (el) {
          const controller = createApp(el, {
            assemblies: volvoxConfig.assemblies,
            tracks: volvoxConfig.tracks,
            views: [
              {
                type: 'LinearSyntenyView',
                init: {
                  views: [{ assembly: 'volvox' }, { assembly: 'volvox_del' }],
                  tracks: ['volvox_del.paf'],
                },
              },
            ],
          })
          return () => {
            controller.destroy()
          }
        }
      }}
    />
  )
}