Skip to content

Latest commit

 

History

5,485 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Merman

A headless Rust implementation of Mermaid for parsing, layout, and rendering.

CI status merman on crates.io Rust API documentation MIT or Apache 2.0

Quick start · One-shot and reuse · Output targets · Cargo features · Ecosystem · Compatibility

merman is the main Rust crate in this repository. It parses Mermaid source into a typed semantic model, computes layout, and renders SVG. Optional features add diagnostics, editor facts, ASCII/Unicode output, PNG, JPEG, and PDF. The native path does not start Node.js, Puppeteer, Chromium, or another JavaScript runtime.

For incremental editor syntax, the repository also publishes tree-sitter-mermaid: a tolerant grammar and query package for Rust, Node.js, browser Workers, and editor integrations.

Merman currently follows mermaid@11.16.1. Its parser, layout, configuration, theming, sanitization, and SVG structure are checked against pinned Mermaid source and fixtures.

Note

This README documents the current main branch. The operation-scoped Renderer API was introduced after the published 0.8.0-alpha.5 tag. If you depend on that release, use its tagged README.

Used by Zed. Zed uses Merman as its Rust Mermaid backend. Read the merged integration.

Quick start

Run the maintained SVG example from a source checkout:

cargo run --locked -p merman --example render_svg > diagram.svg

The same operation in Rust is:

use merman::{OperationControl, RenderOutput, RenderRequest, Renderer, SvgRequest};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let output = Renderer::new().render(RenderRequest::svg(
        "flowchart TD\n  A[Start] --> B[Done]",
        OperationControl::new(),
        SvgRequest::default(),
    ))?;

    let RenderOutput::Svg(Some(svg)) = output else {
        return Err("no Mermaid diagram detected".into());
    };

    print!("{}", svg.svg());
    Ok(())
}

The selected RenderOutput variant contains None when the source has no Mermaid diagram. Cancellation, resource exhaustion, parse errors, and unavailable output capabilities remain separate structured errors.

One-shot and repeated rendering

A Renderer stores defaults. Each RenderRequest describes one independent operation.

Type Role Typical lifetime
Renderer Holds the engine and shared defaults One call or many calls
RenderRequest Borrows the source and selects a target, overrides, and control One operation
OperationControl Carries cooperative cancellation and an optional deadline One operation; clone it for the cancelling task or thread
SemanticArtifact Pairs the parsed render model with its operation context Inspect it, then consume it into one output target

The quick start is the one-shot form: create a renderer, issue one request, and drop it. Merman does not hide this behind a separate source-to-SVG helper; one-shot and repeated work both use Renderer::render().

For a batch or service, keep one configured Renderer when inputs share parse options, runtime policy, site config, or resource limits. It shares settings, not parsed state: every call parses its own source and carries a fresh RenderRequest and, normally, a fresh OperationControl.

If several SVGs will share one DOM, give every request a diagram_id that remains unique after merman::svg::sanitize_svg_id() normalization. If an editor needs to retain analysis between queries, use a host-owned snapshot from merman::editor; a reused renderer is not an editor session.

The self-contained Rust examples cover these cases: render_svg.rs is one-shot, render_many.rs reuses a configured renderer, and embed_multiple_svgs.rs assigns stable IDs for a shared document.

Output targets

Choose one typed target for each request:

Need Start with Cargo feature
Parse a typed Mermaid model Engine and ParseOptions Always available
Prepare or inspect the semantic artifact Renderer::prepare_semantic() or RenderTarget::Semantic Always available
Render Mermaid-style SVG RenderRequest::svg() svg
Inspect layout JSON or an SVG capability plan RenderRequest::layout_json() or RenderRequest::svg_plan() svg
Render terminal text for supported families RenderRequest::ascii() ascii
Export PNG, JPEG, or PDF RenderRequest::png(), jpeg(), or pdf() matching output feature
Produce diagnostics or analyze Markdown and MDX fences merman::analysis::Analyzer analysis
Build parser-backed editor snapshots APIs under merman::editor editor

Cargo features remove unavailable target types at compile time. Within a compiled target, a missing layout engine or runtime adapter returns a typed missing-capability error instead of silently choosing a different result.

Cargo features

The default merman dependency enables complete-svg: SVG rendering, Cytoscape and ELK layouts, and math labels. Analysis, editor APIs, terminal output, binary export, and ambient system adapters remain opt-in.

Cargo features select capabilities and output backends, not Mermaid diagram families. Every parser-capable build retains the same language catalog.

Goal Cargo selection
Complete deterministic SVG defaults, or complete-svg
Basic SVG without optional layout engines or math default-features = false, features = ["svg"]
Diagnostics and editor APIs default-features = false, features = ["analysis", "editor"]
Terminal output default-features = false, features = ["ascii"]
Binary export Add only the required png, jpeg, or pdf feature

The capability guide documents feature forwarding, artifact profiles, system adapters, and resource policy. Parser-only applications can depend on merman-core directly. Applications that need lower-level layout or SVG pipeline control can use the re-exports under merman::svg or depend on merman-render.

Determinism, cancellation, and limits

Renderer::new() uses deterministic engine defaults. SvgRequest::default() supplies the default headless SVG environment. System clock, time-zone, random, and timing adapters are separate Cargo features and must also be selected explicitly at runtime.

Every render request owns an OperationControl. Its clones share cooperative cancellation and an optional monotonic deadline. Cancellation is observed at operation checkpoints; a synchronous host callback already in progress may return before Merman reaches the next checkpoint.

Resource limits are part of the request contract. Missing capabilities and exhausted limits return typed errors rather than partial output or a silent fallback. See the resource and options guide for the complete policy model.

Internal flow

Mermaid source
    |-- tree-sitter-mermaid
    |      `-- tolerant CST ---------------------> highlighting, folding, syntax selection
    |
    `-- Merman semantic parser
           |-- typed model ----------------------> diagnostics, navigation, refactoring
           |-- typed layout ---------------------> Mermaid-style SVG
           |-- validated SVG --------------------> PNG, JPEG, and PDF
           `-- supported typed diagram models ---> ASCII and Unicode

The two parsers have different contracts. Tree-sitter keeps useful syntax structure while a document is incomplete; Merman remains the strict semantic and rendering authority. The semantic model is shared by analysis and rendering. Binary export starts from validated SVG, not a browser screenshot.

Rendered output

Architecture Mindmap Sankey
Architecture diagram rendered by Merman Mindmap rendered by Merman Sankey diagram rendered by Merman

These examples were rendered headlessly by merman-cli, which uses the same Rust parser and rendering pipeline. The Playground covers all 35 built-in diagram families.

Ecosystem

Choose the surface that owns the job instead of pulling the complete renderer into every host:

Need Start with
Parse, lay out, and render from Rust merman
Run shell commands, Markdown batches, linting, or mmdc compatibility merman-cli
Use WebAssembly in a browser or Worker Browser packages
Use native Node.js bindings Node.js package
Build incremental CSTs, syntax highlighting, folding, or selections tree-sitter-mermaid on crates.io or @mermanjs/tree-sitter-mermaid on npm
Add diagnostics, completion, navigation, and rename merman-lsp or the VS Code extension
Integrate C/C++, Python, Flutter, Android, Apple, Typst, or other delivery surfaces Package surface guide

tree-sitter-mermaid is independently versioned because editor syntax trees and queries have a different compatibility contract from Merman's semantic model and renderer. Its package README covers Node.js, browser, Rust, C/C++, query, and downstream-editor integration.

The documentation index covers architecture records, contributor procedures, parity evidence, and release operations. The Typst package and other independently delivered integrations remain listed in the package surface guide.

Rustdoc integrations

Merman offers two static-SVG paths for Rustdoc; neither loads JavaScript or fetches diagrams when a reader opens the generated documentation.

Choose When
merman-cli Rustdoc guide Generate and commit checked Markdown fragments without adding a renderer to the documented crate's Cargo graph
merman-rustdoc Render annotated Mermaid blocks during cargo doc through an opt-in procedural macro and native renderer closure

The dedicated guides cover configuration, CI freshness, docs.rs, packaging, generated ownership, and migration. The two paths are explicit alternatives; neither silently falls back to the other.

Compatibility

Merman aims for source-backed agreement in parsing, semantic models, layout, configuration, theming, sanitization, and SVG DOM structure. It does not promise byte-for-byte Chromium pixels.

Browser font fallback, getBBox() floats, foreignObject, HTML labels, and RoughJS path geometry can still produce documented differences where a robust headless equivalent is unavailable. Mermaid-style SVG may contain HTML labels. Use SvgPipeline::resvg_safe() or a typed PNG, JPEG, or PDF target when the consumer cannot render foreignObject.

Read the alignment dashboard, SVG output pipeline, rendering security guide, and benchmark methodology for the current evidence boundary.

Development

cargo nextest run --workspace
cargo fmt --all -- --check
cargo run -p xtask -- verify --strict

The strict gate checks generated contracts, all-family SVG evidence, package surfaces, browser tests, and release legal material against the pinned reference bundle.

License and attribution

Merman is available under the Apache License 2.0 or MIT License.

Source translations, fixtures, embedded resources, behavioral references, and their exact revisions are recorded in THIRD_PARTY_NOTICES.md and the machine-readable component inventory.

Merman is independent of, and not affiliated with, endorsed by, or sponsored by the Mermaid project or its maintainers.

About

Mermaid.js, but headless, in Rust.

Topics

Resources

Stars

520 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages