nj 0.0.18

Neighbor-Joining phylogenetic tree inference. Auto-detects DNA/protein, supports multiple substitution models and bootstrap.
Documentation

nj.rs

Neighbor-Joining phylogenetic tree inference in Rust, with Python and WASM bindings.

Release Tests

Crates.io Version PyPI - Version NPM Version

Takes an aligned FASTA file as input and outputs a Newick string. Alphabet (DNA/protein) is auto-detected. Supports optional bootstrap support values on internal nodes.

Substitution models: PDiff (DNA + protein), JukesCantor (DNA), Kimura2P (DNA), Poisson (protein)

CLI

cargo install nj --features cli

nj sequences.fasta
nj --substitution-model kimura2-p --n-bootstrap-samples 100 sequences.fasta > tree.nwk

A progress bar is shown on stderr when bootstrapping.

Rust

[dependencies]
nj = "0.0.12"
use nj::{NJConfig, SequenceObject, nj, models::SubstitutionModel};

let newick = nj(NJConfig {
    msa: vec![
        SequenceObject { identifier: "A".into(), sequence: "ACGT".into() },
        SequenceObject { identifier: "B".into(), sequence: "ACCT".into() },
    ],
    n_bootstrap_samples: 100,
    substitution_model: SubstitutionModel::JukesCantor,
}, Some(Box::new(|current, total| println!("{current}/{total}"))))?;

Python

pip install nj_py
from tqdm import tqdm
from nj_py import nj

msa = [
    {"identifier": "A", "sequence": "ACGT"},
    {"identifier": "B", "sequence": "ACCT"},
]

with tqdm(total=100) as bar:
    newick = nj(
        msa,
        substitution_model="JukesCantor",
        n_bootstrap_samples=100,
        on_progress=lambda current, total: bar.update(1),
    )

JavaScript / WASM

npm install @holmrenser/nj
import { nj } from '@holmrenser/nj';

const config = {
    msa: [
        { identifier: 'A', sequence: 'ACGT' },
        { identifier: 'B', sequence: 'ACCT' },
    ],
    n_bootstrap_samples: 100,
    substitution_model: 'JukesCantor',
};

const newick = nj(config, (current, total) => {
    progressBar.value = current / total * 100;
});