npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

reactreejs

v1.0.3

Published

Interactive phylogenetic tree viewer for React

Downloads

336

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

| 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