Faithful Rust ports of mature upstream projects

Native Rust integration

use pandoc; straight from your Cargo.toml — no Command::new("pandoc"), no FFI bindgen, no shared libraries to ship. Every port is published as both a library crate and a CLI binary.

Faithful, not a rewrite

Each port mirrors the upstream's structure: same function names, same branch order, same error messages. The Rust code diffs line by line against the original — behavior matches because structure matches.

Tracks the upstream

Each port pins a specific upstream tag (0.1.0+upstream.3.9.0.2). Future upstream changes merge at translation cost, not redesign cost. The port doesn't become an abandoned fork.

Performance and memory footprint

Native code, no interpreter or VM, no garbage collector. biber-rs already runs faster than upstream Perl biber on the full fixture corpus. Matching a tightly-tuned C engine like quickjs is the harder target and an open challenge. Published benchmarks are coming.

Use it from your crate

The crates aren't on crates.io yet; depend on them by git URL for now.

Add the ports you want to your Cargo.toml:

# Cargo.toml [dependencies] biber = { git = "https://github.com/rustports/biber", package = "rustports-biber" } quickjs = { git = "https://github.com/rustports/quickjs", package = "rustports-quickjs" } pandoc = { git = "https://github.com/rustports/pandoc", package = "rustpandoc" }

Then call into them like any other crate:

// src/main.rs use quickjs::runtime::Runtime; fn main() -> Result<(), Box<dyn std::error::Error>> { let mut rt = Runtime::new(); let value = rt.eval("40 + 2")?; println!("{value}"); Ok(()) }

The exact API surface varies per port — see each crate's README and rustdoc for the entry points.

Available ports

pandoc, biber, quickjs, plus the supporting Haskell library chain pandoc depends on.

See the catalog with status →

How it works

Each port lives in its own repo under github.com/rustports, with the upstream source vendored as a git submodule pinned to a specific tag. The Rust code mirrors the upstream structure — function for function, branch for branch — so a future upstream change is a mechanical translation rather than a redesign.

A differential test harness compares the port's output to the upstream's, byte for byte, on the upstream's own test corpus. A port doesn't ship until its harness reports green on the cases it claims to cover; status numbers on the packages page come from that harness.

For the longer story — why faithful structure matters more than passing tests, when to mirror and when to adapt — see What's a faithful port? or read the full methodology.