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.
- Features
- Installation
- Quick start
- With a sequence alignment
- Props
- CSS import
- Dark mode
- Theming with CSS variables
- Tree editing tools
- Alignment panel
- Export
- Server-side rendering
- Newick format
- FASTA matching
- TypeScript
- Browser support
- License
| 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 |
npm install reactreejsPeer dependencies (install separately if not already in your project):
npm install react react-domSupported peer versions: React 18 and 19.
import{Reactree}from'reactreejs';import'reactreejs/style.css';exportdefaultfunctionApp(){constnewick='((Homo_sapiens:0.09,Pan_troglodytes:0.11):0.07,(Mus_musculus:0.23,Rattus_norvegicus:0.21):0.14);';return<Reactreenewick={newick}/>;}The stylesheet import is required — see CSS import.
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';constnewick='((Homo_sapiens:0.09,Anopheles:0.36):0.07,Mimivirus:1.22);';constfasta=`>Homo_sapiensMTEYKLVVVGAGGVGKSALTIQLIQNHFVDEYDPTIEDSY>AnophelesMTEYKLVVVGAGGVGKSALTIQLIQNHFVDEYDPTIEDS->Mimivirus----KLVVVGAGGVGKSALTIQL-QNHFVDEYDPTIEDS-`.trim();exportdefaultfunctionApp(){return(<Reactreenewick={newick}fasta={fasta}defaultHeight={600}/>);}Sequence type (nucleotide vs. amino acid) is detected automatically from the sequence content.
| 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. |
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.
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:
functionThemeToggle(){const[dark,setDark]=React.useState(false);functiontoggle(){constnext=!dark;setDark(next);if(next){document.documentElement.setAttribute('data-theme','dark');}else{document.documentElement.removeAttribute('data-theme');}}return<buttononClick={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.
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;
}| 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 |
| 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 |
| Variable | Default | Role |
|---|---|---|
--font-family | 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif | UI font (toolbar, labels, panels) |
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 */
}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) |
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.
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 |
| Single-page PDF via jsPDF, suitable for figures | |
| Newick | Exports the current (possibly rerooted/rearranged) tree as a Newick string |
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:
importdynamicfrom'next/dynamic';constReactree=dynamic(()=>import('reactreejs').then(m=>m.Reactree),{ssr: false});exportdefaultfunctionPage(){return<Reactreenewick="((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.
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.
Leaf names are matched to FASTA sequence headers by a two-step lookup:
- Exact match after normalising underscores to spaces and lower-casing both sides.
- 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.
Types for the component props are exported from the package:
importtype{ReactreeProps}from'reactreejs';typeReactreeProps={newick: string;defaultHeight?: number;fasta?: string;};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.
MIT