A fast native Rust Mermaid diagram renderer. No browser required. 500-1000x faster than mermaid-cli.
  • Rust 82.8%
  • Python 13.1%
  • Mermaid 2.2%
  • HTML 1.7%
  • Shell 0.2%
Find a file
2026-02-11 02:22:37 -08:00
.github Bump actions/checkout from 4 to 6 2026-01-27 19:59:05 +00:00
benches Improve layout routing quality and expand visual benchmarks 2026-02-09 01:59:07 -08:00
docs Improve flowchart edge routing order and hub side balancing 2026-02-10 17:09:01 -08:00
scripts Add generic SSH remote Cargo runner 2026-02-11 02:22:37 -08:00
src Improve flowchart subgraph packing and edge label anchor selection 2026-02-11 01:41:36 -08:00
tests Add fast text metrics option 2026-02-01 18:43:23 -08:00
tmp Fix ER diagram crow's foot notation rendering 2026-01-26 00:05:41 -08:00
.gitignore Improve flowchart layout quality and edge label placement 2026-02-07 14:17:07 -08:00
Cargo.lock Release v0.2.0 2026-02-07 15:20:24 -08:00
Cargo.toml Release v0.2.0 2026-02-07 15:20:24 -08:00
CHANGELOG.md Release v0.2.0 2026-02-07 15:20:24 -08:00
clippy.toml Fix clippy warnings to pass CI 2026-01-24 17:16:00 -08:00
LICENSE Add MIT license 2026-01-22 15:54:30 -08:00
package-lock.json Fix ER diagram crow's foot notation rendering 2026-01-26 00:05:41 -08:00
package.json Fix ER diagram crow's foot notation rendering 2026-01-26 00:05:41 -08:00
README.md Add generic SSH remote Cargo runner 2026-02-11 02:22:37 -08:00

mmdr

1001400x faster Mermaid rendering. Pure Rust. Zero browser dependencies.

Installation | Quick Start | Benchmarks | Examples

Performance

mmdr renders diagrams 1001400x faster than mermaid-cli by eliminating browser overhead. With the built-in font cache (warm after first run), tiny diagrams reach 500900× (and --fastText exceeds 1600×).

Performance comparison

Diagram mmdr mermaid-cli Speedup
Flowchart 4.49 ms 1,971 ms 439x
Class Diagram 4.67 ms 1,907 ms 408x
State Diagram 3.97 ms 1,968 ms 496x
Sequence Diagram 2.71 ms 1,906 ms 704x

Tested on Intel Core Ultra 7 265V, Linux 6.18.7 | mermaid-cli 11.4.2 via Puppeteer/Chromium

Font cache (default, warm after first run)

Once the font cache is populated, tiny/common diagrams reach 500900×:

Diagram (tiny) mmdr (warm cache) mermaid-cli Speedup
Flowchart 2.96 ms 2,259 ms 764×
Class 2.55 ms 2,347 ms 919×
State 2.67 ms 2,111 ms 789×
Sequence 3.75 ms 2,010 ms 536×

Measured Feb 2, 2026 on the same machine.

Fast text metrics (optional, fastest)

Enable --fastText to use calibrated fallback widths for ASCII labels (avoids font DB load). On tiny/common diagrams this reaches 16002069× speedups:

Diagram (tiny) mmdr --fastText mermaid-cli Speedup
Flowchart 1.32 ms 2,116 ms 1,601×
Class 1.23 ms 2,314 ms 1,880×
State 1.09 ms 2,258 ms 2,069×
Sequence 1.16 ms 2,158 ms 1,868×

Measured Feb 2, 2026 on the same machine.

Pipeline breakdown

Library Performance (no CLI overhead)

When used as a Rust library, mmdr is even faster with no process spawn overhead:

Library performance

Diagram Library Time
Flowchart 1.49 ms
Class Diagram 2.51 ms
State Diagram 2.04 ms
Sequence Diagram 0.07 ms

These are raw render times measured with Criterion, ideal for embedding in applications.

Extended Benchmarks

Performance on larger diagrams:

Diagram Nodes mmdr mermaid-cli Speedup
flowchart (small) 10 3.38 ms 1,910 ms 565x
flowchart (medium) 50 8.71 ms 2,018 ms 232x
flowchart (large) 200 47.00 ms 2,276 ms 48x

The speedup advantage decreases for very large diagrams as actual layout computation becomes more significant relative to browser startup overhead. Still, mmdr remains 100x+ faster even for 200-node diagrams.

Why mmdr?

The official mermaid-cli spawns a headless Chromium browser for every diagram, adding 2-3 seconds of startup overhead.

Use Case mermaid-cli mmdr
CI/CD pipeline with 50 diagrams ~2 minutes < 1 second
Real-time editor preview Unusable lag Instant
Batch doc generation Coffee break Blink of an eye

mmdr parses Mermaid syntax natively in Rust and renders directly to SVG. No browser. No Node.js. No Puppeteer.

Installation

# From source
cargo install --path .

# Homebrew (macOS/Linux)
brew tap 1jehuang/mmdr && brew install mmdr

# Scoop (Windows)
scoop bucket add mmdr https://github.com/1jehuang/scoop-mmdr && scoop install mmdr

# AUR (Arch)
yay -S mmdr-bin

Quick Start

# Pipe diagram to stdout
echo 'flowchart LR; A-->B-->C' | mmdr -e svg

# File to file
mmdr -i diagram.mmd -o output.svg -e svg
mmdr -i diagram.mmd -o output.png -e png

# Render all diagrams from a Markdown file
mmdr -i README.md -o ./diagrams/ -e svg

Diagram Types

mmdr supports 23 Mermaid diagram types:

Category Diagrams
Core Flowchart, Sequence, Class, State
Data ER Diagram, Pie Chart, XY Chart, Quadrant Chart, Sankey
Planning Gantt, Timeline, Journey, Kanban
Architecture C4, Block, Architecture, Requirement
Other Mindmap, Git Graph, ZenUML, Packet, Radar, Treemap
Flowchart
Flowchart
Class Diagram
Class Diagram
State Diagram
State Diagram
Sequence Diagram
Sequence Diagram
Compare with mermaid-cli output
Type mmdr mermaid-cli
Flowchart
Class
State
Sequence
ER Diagram
Pie Chart
Gantt
Mindmap
Timeline
Journey
Git Graph
XY Chart
Quadrant

More Diagrams

Node Shapes
Shape Syntax
Rectangle [text]
Round (text)
Stadium ([text])
Diamond {text}
Hexagon {{text}}
Cylinder [(text)]
Circle ((text))
Double Circle (((text)))
Subroutine [[text]]
Parallelogram [/text/]
Trapezoid [/text\]
Asymmetric >text]
Edge Styles
Type Syntax Description
Arrow --> Standard arrow
Open --- No arrowhead
Dotted -.-> Dashed line with arrow
Thick ==> Bold arrow
Circle end --o Circle decoration
Cross end --x X decoration
Diamond end <--> Bidirectional
With label --|text|--> Labeled edge
Subgraphs
flowchart TB
    subgraph Frontend
        A[React App] --> B[API Client]
    end
    subgraph Backend
        C[Express Server] --> D[(PostgreSQL)]
    end
    B --> C

Subgraphs support:

  • Custom labels
  • Direction override (direction LR)
  • Nesting
  • Styling
Styling Directives
flowchart LR
    A[Start] --> B[End]

    classDef highlight fill:#f9f,stroke:#333
    class A highlight

    style B fill:#bbf,stroke:#333
    linkStyle 0 stroke:red,stroke-width:2px

Supported:

  • classDef - Define CSS classes
  • class - Apply classes to nodes
  • :::class - Inline class syntax
  • style - Direct node styling
  • linkStyle - Edge styling
  • %%{init}%% - Theme configuration

Features

Diagram types: flowchart / graph | sequenceDiagram | classDiagram | stateDiagram-v2 | erDiagram | pie | gantt | journey | timeline | mindmap | gitGraph | xychart-beta | quadrantChart | sankey-beta | kanban | C4Context | block-beta | architecture-beta | requirementDiagram | zenuml | packet-beta | radar-beta | treemap

Node shapes: rectangle, round-rect, stadium, circle, double-circle, diamond, hexagon, cylinder, subroutine, trapezoid, parallelogram, asymmetric

Edges: solid, dotted, thick | Decorations: arrow, circle, cross, diamond | Labels

Styling: classDef, class, :::class, style, linkStyle, %%{init}%%

Layout: subgraphs with direction, nested subgraphs, automatic spacing

Configuration

mmdr -i diagram.mmd -o out.svg -c config.json
mmdr -i diagram.mmd -o out.svg --nodeSpacing 60 --rankSpacing 120
config.json example
{
  "themeVariables": {
    "primaryColor": "#F8FAFF",
    "primaryTextColor": "#1C2430",
    "primaryBorderColor": "#C7D2E5",
    "lineColor": "#7A8AA6",
    "secondaryColor": "#F0F4FF",
    "tertiaryColor": "#E8EEFF",
    "edgeLabelBackground": "#FFFFFF",
    "clusterBkg": "#F8FAFF",
    "clusterBorder": "#C7D2E5",
    "background": "#FFFFFF",
    "fontFamily": "Inter, system-ui, sans-serif",
    "fontSize": 13
  },
  "flowchart": {
    "nodeSpacing": 50,
    "rankSpacing": 50
  }
}

How It Works

Architecture comparison

mmdr implements the entire Mermaid pipeline natively:

.mmd → parser.rs → ir.rs → layout.rs → render.rs → SVG → resvg → PNG

mermaid-cli requires browser infrastructure:

.mmd → mermaid-js → layout → Browser DOM → Puppeteer → Chromium → Screenshot → PNG
mmdr mermaid-cli
Runtime Native binary Node.js + Chromium
Cold start ~3 ms ~2,000 ms
Memory ~15 MB ~300+ MB
Dependencies None Node.js, npm, Chromium

Library Usage

Use mmdr as a Rust library in your project:

[dependencies]
mermaid-rs-renderer = { git = "https://github.com/1jehuang/mermaid-rs-renderer", tag = "v0.2.0" }
Minimal dependencies (for embedding)

For tools like Zola that only need SVG rendering, disable default features to avoid CLI and PNG dependencies:

[dependencies]
mermaid-rs-renderer = { git = "https://github.com/1jehuang/mermaid-rs-renderer", tag = "v0.2.0", default-features = false }
Feature Default Description
cli Yes CLI binary and clap dependency
png Yes PNG output via resvg/usvg

This reduces dependencies from ~180 to ~80 crates.

use mermaid_rs_renderer::{render, render_with_options, RenderOptions};

// Simple one-liner
let svg = render("flowchart LR; A-->B-->C").unwrap();

// With custom options
let opts = RenderOptions::modern()
    .with_node_spacing(60.0)
    .with_rank_spacing(80.0);
let svg = render_with_options("flowchart TD; X-->Y", opts).unwrap();
Full pipeline control
use mermaid_rs_renderer::{
    parse_mermaid, compute_layout, render_svg,
    Theme, LayoutConfig,
};

let diagram = "flowchart LR; A-->B-->C";

// Stage 1: Parse
let parsed = parse_mermaid(diagram).unwrap();
println!("Parsed {} nodes", parsed.graph.nodes.len());

// Stage 2: Layout
let theme = Theme::modern();
let config = LayoutConfig::default();
let layout = compute_layout(&parsed.graph, &theme, &config);

// Stage 3: Render
let svg = render_svg(&layout, &theme, &config);
With timing information
use mermaid_rs_renderer::{render_with_timing, RenderOptions};

let result = render_with_timing(
    "flowchart LR; A-->B",
    RenderOptions::default()
).unwrap();

println!("Rendered in {:.2}ms", result.total_ms());
println!("  Parse:  {}us", result.parse_us);
println!("  Layout: {}us", result.layout_us);
println!("  Render: {}us", result.render_us);

Development

cargo test
cargo run -- -i docs/diagrams/architecture.mmd -o /tmp/out.svg -e svg

Remote build/test over SSH (optional):

export MMDR_REMOTE_HOST=<your-ssh-host-alias>
scripts/remote-cargo.sh test
scripts/remote-cargo.sh build --release
scripts/remote-cargo.sh bench --bench renderer

The wrapper uses rsync + ssh and keeps host/IP details in your local environment or ~/.ssh/config, not in this repository.

Benchmarks:

cargo bench --bench renderer              # Microbenchmarks
cargo build --release && python scripts/bench_compare.py  # vs mermaid-cli

License

MIT