React components for biological data visualization.
Documentation, with live examples: holmrenser.github.io/react-bio-viz
- MultipleSequenceAlignment — windowed canvas rendering (no size limit; letters crisp at any zoom) with pan/zoom, column ruler, minimap, consensus row, residue search, the standard colour schemes (ClustalX, Zappo, Taylor) plus analysis and score styles, conservation/logo/score tracks, row and column selection, drag-to-reorder rows, and rename/remove callbacks for editing.
- PhyloTree — rectangular, cladogram and radial layouts, with branch rerooting (and midpoint rooting), collapsible clades, drag-to-reorder (or drag past either end to reroot), node and branch click callbacks, per-node/branch styles, search, and Newick parse/serialise helpers.
- DistanceMatrix — a pairwise distance heatmap that scales to thousands of rows, sharing its row order with an alignment.
- GeneModel — transcripts, exons and CDSs over a genomic axis.
- GenomeBrowser — stacked feature/coverage/gene-model tracks sharing one viewport.
- BlastHitDistribution — BLAST hits along a query, row-stacked and coloured by e-value, bit score or percent identity.
npm install react-bio-vizWorks with React 18 and 19.
import { GeneModel, MultipleSequenceAlignment, PhyloTree } from 'react-bio-viz';
function App() {
return (
<div>
<GeneModel gene={gene} />
<MultipleSequenceAlignment
msa={msa}
options={{ cellSize: 16, showLabels: true, colorStyle: 'AA ClustalX' }}
/>
<PhyloTree tree={tree} layout="radial" interactive />
</div>
);
}There is no stylesheet to import: the components add theirs to the page on import. It never
restyles the rest of your page, and your own theme tokens (--background, --font-sans, …) take
precedence over its defaults. It also ships as react-bio-viz/style.css, for server-rendered pages,
strict Content Security Policies, and shadow roots — see
Getting started.
Every piece of interactive state — a viewport, a tree selection, a set of selected BLAST hits —
follows one contract, so learning it once covers every component. Each is a group of four props
named for its domain (viewport / defaultViewport / onViewportChange / viewportStore;
selection / defaultSelection / onSelectionChange / selectionStore) supporting three modes:
// Uncontrolled: the component owns the state, but you can still observe every change.
<MultipleSequenceAlignment msa={msa} onViewportChange={console.log} />
// Controlled: you own it, exactly like a controlled <input>.
<MultipleSequenceAlignment msa={msa} viewport={viewport} onViewportChange={setViewport} />
// External store: the component reads and writes a store you own, which views can share.
const viewportStore = createControllableStore(initialViewport);
<MultipleSequenceAlignment msa={msa} viewportStore={viewportStore} />Each component also comes as a bare, fully controlled view — SimpleMultipleSequenceAlignment,
SimplePhyloTree, … — without the toolbar and holding no state, for building your own navigation.
The same StoreController seam is what the Jupyter bindings below plug into — a notebook is just
another external-store consumer, so no component contains any Jupyter-specific code.
The same components are published to PyPI as Jupyter widgets, where each piece of interactive state is a synced traitlet:
pip install react-bio-vizfrom react_bio_viz import MSA
widget = MSA(msa=[{"identifier": "seq1", "sequence": "MKTAYIAKQRQISFVK"}])
widget.observe(lambda change: print(change["new"]), names="viewport")
widgetThe example notebook takes an alignment through
distances and a neighbour-joining tree, with all three views linked. See also
packages/python/README.md.
The documentation site has guides, a live example for every component, the Jupyter
widgets, and an API reference generated from the TSDoc comments. Its source is apps/docs
(Astro Starlight), deployed to GitHub Pages by .github/workflows/docs.yml.
This is a pnpm workspace monorepo:
packages/core/ @react-bio-viz/core shared primitives + shadcn/ui chrome
packages/components/ react-bio-viz the components
packages/python/ react-bio-viz (PyPI) anywidget/Jupyter bindings
apps/demo/ Vite playground
apps/docs/ documentation site (Astro Starlight)
pnpm install
pnpm build # core -> components -> the Python widget bundle
pnpm dev # the demo playground
pnpm test # Vitest across packages
pnpm typecheck
pnpm lint
pnpm run docs # build the documentation site into apps/docs/dist (`pnpm docs` is a pnpm built-in)
pnpm docs:dev # the documentation site with live reloadFor the Python package, from packages/python: uv pip install -e ".[dev]" then pytest.
Conventions for contributors (and AI agents) live in AGENTS.md and
.agents/skills/bio-viz-conventions/SKILL.md.
MIT
