Skip to content

vaaloo/reactreejs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

reactreejs

A React component for rendering interactive phylogenetic trees from Newick strings. Supports rectangular and circular layouts, zoom/pan, a full editing toolkit, and an optional synchronized sequence alignment panel.

Built on D3 and packaged as a zero-config drop-in — one import, one prop.


Contents


Features

Category Capabilities
Layout Rectangular and circular trees; phylogram (branch-length scaled) and cladogram (uniform) modes
Navigation Zoom with mouse wheel, pan by dragging, fit-to-view button
Editing Reroot (click any node or midpoint), flip branches, swap sibling clades, ladderize ascending/descending
Collapse Click any internal node to collapse into a named, colored triangle; rename and recolor via an inline editor
Coloring Paint any node, clade, or subtree with a color picker; reset individual nodes or all at once
Labels Toggle leaf labels, bootstrap values, branch lengths; right-align labels with dotted leader lines (phylogram)
Search Highlight matching taxa by name; keyboard navigation (⌘F / Ctrl+F, Enter, Esc)
Alignment Synchronized FASTA viewer with nucleotide and amino acid color schemes, scrolls in sync with the tree
Export Download as SVG, PNG, PDF, or Newick
Dark mode Full dark theme controlled by data-theme="dark" on <html>
Resize Drag handle at the bottom of the viewer to adjust height at runtime

Installation

npm install reactreejs

Peer dependencies (install separately if not already in your project):

npm install react react-dom

Supported peer versions: React 18 and 19.


Quick start

import { Reactree } from 'reactreejs';
import 'reactreejs/style.css';

export default function App() {
  const newick = '((Homo_sapiens:0.09,Pan_troglodytes:0.11):0.07,(Mus_musculus:0.23,Rattus_norvegicus:0.21):0.14);';

  return <Reactree newick={newick} />;
}

The stylesheet import is required — see CSS import.


With a sequence alignment

Pass a fasta string to enable the alignment panel. An Alignment toggle button will appear in the toolbar. When activated, a synchronized sequence viewer opens alongside the tree, scrolling in sync as you pan.

import { Reactree } from 'reactreejs';
import 'reactreejs/style.css';

const newick = '((Homo_sapiens:0.09,Anopheles:0.36):0.07,Mimivirus:1.22);';

const fasta = `
>Homo_sapiens
MTEYKLVVVGAGGVGKSALTIQLIQNHFVDEYDPTIEDSY
>Anopheles
MTEYKLVVVGAGGVGKSALTIQLIQNHFVDEYDPTIEDS-
>Mimivirus
----KLVVVGAGGVGKSALTIQL-QNHFVDEYDPTIEDS-
`.trim();

export default function App() {
  return (
    <Reactree
      newick={newick}
      fasta={fasta}
      defaultHeight={600}
    />
  );
}

Sequence type (nucleotide vs. amino acid) is detected automatically from the sequence content.


Props

Prop Type Required Default Description
newick string Yes Newick tree string. Supports branch lengths (:0.123) and internal node labels (used as bootstrap values).
defaultHeight number No 520 Initial viewer height in pixels. The user can resize at runtime via the drag handle.
fasta string No Multi-FASTA sequence string. Enables the alignment panel. Sequences are matched to leaf names by case-insensitive, underscore-normalised lookup.

CSS import

The component stylesheet must be imported explicitly — without it, layout, spacing, and theming will not work:

import 'reactreejs/style.css';

Import it once, at the top level of your application (e.g. main.tsx, _app.tsx, or your root layout). Do not import it more than once.

The stylesheet defines all design tokens as CSS custom properties on :root. You can override any of them after the import — see Theming with CSS variables.


Dark mode

reactreejs reads the data-theme attribute on <html> and reacts to changes via a MutationObserver. No context providers or additional configuration are needed.

Enable dark mode:

document.documentElement.setAttribute('data-theme', 'dark');

Return to light mode:

document.documentElement.removeAttribute('data-theme');
// or equivalently:
document.documentElement.setAttribute('data-theme', 'light');

React toggle example:

function ThemeToggle() {
  const [dark, setDark] = React.useState(false);

  function toggle() {
    const next = !dark;
    setDark(next);
    if (next) {
      document.documentElement.setAttribute('data-theme', 'dark');
    } else {
      document.documentElement.removeAttribute('data-theme');
    }
  }

  return <button onClick={toggle}>{dark ? 'Light' : 'Dark'} mode</button>;
}

Respecting the OS preference on first load:

if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
  document.documentElement.setAttribute('data-theme', 'dark');
}

The component switches instantly — the MutationObserver fires on every attribute change and triggers a re-render.


Theming with CSS variables

All visual tokens are exposed as CSS custom properties. Import reactreejs/style.css, then override whatever you need in your own stylesheet:

/* your-app.css — loaded after reactreejs/style.css */
:root {
  --clr-primary-a0: #7c3aed;   /* accent color (buttons, highlights) */
  --clr-surface-a0: #fafaf9;   /* main background */
  --font-family: 'Inter', sans-serif;
}

Full token reference

Colors — light mode (:root defaults)

Variable Default Role
--clr-primary-a0 #0071f2 Accent — active buttons, focus rings, highlights
--clr-surface-a0 #ffffff Main background (toolbar, panels)
--clr-surface-a10 #f8fafc Secondary surface (input backgrounds)
--clr-surface-a20 #f1f5f9 Tertiary surface (hover states)
--clr-text-primary #0f172a Primary text
--clr-text-secondary #475569 Secondary / muted text
--clr-border #e2e8f0 Borders and dividers
--clr-input-bg #f8fafc Input field backgrounds

Colors — dark mode ([data-theme="dark"] overrides)

Variable Dark value Role
--clr-primary-a0 #3b82f6 Accent — brighter blue for dark backgrounds
--clr-surface-a0 #0f172a Main background
--clr-surface-a10 #1e293b Secondary surface
--clr-surface-a20 #334155 Tertiary surface / hover
--clr-text-primary #f8fafc Primary text
--clr-text-secondary #94a3b8 Secondary / muted text
--clr-border #334155 Borders and dividers
--clr-input-bg #1e293b Input field backgrounds

Typography

Variable Default Role
--font-family 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif UI font (toolbar, labels, panels)

Overriding dark mode tokens independently

You can override tokens for dark mode only by targeting the same selector:

[data-theme='dark'] {
  --clr-primary-a0: #a78bfa;  /* softer violet accent in dark mode */
  --clr-surface-a0: #020617;  /* deeper background */
}

Tree editing tools

All editing tools are available in the toolbar above the tree. Operations are non-destructive — an Undo button (⌘Z / Ctrl+Z) steps back through the edit history, and Reset returns to the original tree.

Tool Description
Rect / Circ Switch between rectangular and circular (radial) layout
Phylogram / Cladogram Toggle branch-length scaling on or off
Reroot Click any node to set it as the new root; or use Midpoint to root at the midpoint of the longest path
Flip Reverse the child order of any internal node
Swap Select two sibling nodes to swap their positions
Ladderize Sort all clades by leaf count, ascending or descending
Color Paint any node or clade with a color picker; Reset clears individual nodes
Align labels Right-align leaf labels with dotted leader lines (phylogram only)
Bootstrap / Branch length Toggle label display on internal nodes
Collapse Click an internal node to collapse into a named triangle; click again to open the editor and rename or recolor it
Search Filter and highlight taxa by name (⌘F / Ctrl+F)

Alignment panel

When fasta is provided, a toggle button labeled Alignment appears in the toolbar. Clicking it opens a sequence panel to the right of the tree.

  • Sequences scroll vertically in sync with the tree — the row for each taxon stays aligned with its leaf label.
  • Color schemes switch automatically based on detected sequence type: nucleotide (A/T/C/G coloring) or amino acid (residue-class coloring).
  • A legend for the active color scheme is shown at the top of the alignment panel.
  • Horizontal scrolling is independent from the tree.

Sequence matching is case-insensitive and underscore-tolerant — Homo_sapiens in the tree will match >Homo sapiens in the FASTA header, and vice versa.


Export

The Download menu in the toolbar provides four formats:

Format Notes
SVG Lossless vector, includes the full tree as rendered
PNG Rasterised at the current viewport size
PDF Single-page PDF via jsPDF, suitable for figures
Newick Exports the current (possibly rerooted/rearranged) tree as a Newick string

Server-side rendering

reactreejs uses D3, the Canvas API, and document/window directly. It is not compatible with SSR as-is.

Next.js — dynamic import with ssr: false:

import dynamic from 'next/dynamic';

const Reactree = dynamic(
  () => import('reactreejs').then(m => m.Reactree),
  { ssr: false }
);

export default function Page() {
  return <Reactree newick="((A:0.1,B:0.2):0.3,C:0.4);" />;
}

Remix / other SSR frameworks: wrap the import in a useEffect or use a client-only boundary to ensure it loads exclusively in the browser.


Newick format

The parser accepts standard Newick with optional branch lengths and optional internal node labels:

((A:0.1,B:0.2):0.3,(C:0.4,D:0.1):0.2);        # branch lengths
((A,B)90,(C,D)85);                               # bootstrap values as internal labels
((A:0.1,B:0.2)90:0.3,(C:0.4,D:0.1)85:0.2);     # both
(A,B,C);                                         # no lengths, no bootstraps

The trailing semicolon is optional. Internal node labels that parse as numbers in the range [0, 100] are treated as bootstrap support values and displayed when the Bootstrap label mode is active.


FASTA matching

Leaf names are matched to FASTA sequence headers by a two-step lookup:

  1. Exact match after normalising underscores to spaces and lower-casing both sides.
  2. Partial match — if no exact match is found, the first header that contains the leaf name (or vice versa) is used.

Leaves with no matching sequence are shown in the tree normally; their alignment row is simply empty.


TypeScript

Types for the component props are exported from the package:

import type { ReactreeProps } from 'reactreejs';
type ReactreeProps = {
  newick: string;
  defaultHeight?: number;
  fasta?: string;
};

Browser support

reactreejs targets modern evergreen browsers (Chrome, Firefox, Safari, Edge). It requires:

  • ES2020 (optional chaining, nullish coalescing)
  • SVG and Canvas API support
  • MutationObserver (for dark mode reactivity)

It is not tested in Internet Explorer and will not work there.


License

MIT

About

A modern React library for interactive phylogenetic tree visualization, supporting Newick trees, zooming, panning, rerooting, clade interaction, and customizable layouts.

Topics

Resources

License

Stars

Watchers

Forks

Contributors