Performance
mmdr renders diagrams 100-600x faster than mermaid-cli by eliminating browser overhead.
| Diagram | mmdr | mermaid-cli | Speedup |
|---|---|---|---|
| Flowchart | 7.18 ms | 2,252 ms | 313x |
| Class Diagram | 9.09 ms | 2,317 ms | 255x |
| State Diagram | 9.32 ms | 2,255 ms | 242x |
| Sequence Diagram | 6.19 ms | 2,471 ms | 399x |
Tested on Intel Core Ultra 7 265V, Linux 6.18.2 | mermaid-cli 11.4.2 via Puppeteer/Chromium
Library Performance (no CLI overhead)
When used as a Rust library, mmdr is even faster with no process spawn overhead:
| 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 | 7.38 ms | 2,082 ms | 282x |
| flowchart (medium) | 50 | 9.21 ms | 2,287 ms | 248x |
| flowchart (large) | 200 | 26.32 ms | 2,829 ms | 108x |
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 13 Mermaid diagram types:
| Category | Diagrams |
|---|---|
| Core | Flowchart, Sequence, Class, State |
| Data | ER Diagram, Pie Chart, XY Chart, Quadrant Chart |
| Planning | Gantt, Timeline, Journey |
| Other | Mindmap, Git Graph |
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 classesclass- Apply classes to nodes:::class- Inline class syntaxstyle- Direct node stylinglinkStyle- Edge styling%%{init}%%- Theme configuration
Features
Diagram types: flowchart / graph | sequenceDiagram | classDiagram | stateDiagram-v2 | erDiagram | pie | gantt | journey | timeline | mindmap | gitGraph | xychart-beta | quadrantChart
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
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" }
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", 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 svgBenchmarks:
cargo bench --bench renderer # Microbenchmarks cargo build --release && python scripts/bench_compare.py # vs mermaid-cli
License
MIT