reactreejs
v1.0.3
Published
Interactive phylogenetic tree viewer for React
Downloads
336
Maintainers
Readme
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
- 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
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 reactreejsPeer dependencies (install separately if not already in your project):
npm install react react-domSupported 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 bootstrapsThe 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:
- 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.
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
