Fast native Mermaid diagram rendering (Rust, via PyO3) - no browser required
Project description
mmdr
Render Mermaid diagrams from Python or the command line — fast, native, no browser required.
Most Mermaid rendering tools work by spinning up a headless browser and running the official JavaScript library. This works, but it's slow to start, heavy to install, and awkward to embed in a pipeline. mmdr takes a different approach: the rendering engine is written in Rust and ships as a compiled Python extension. Install it with pip, import it, and start rendering — no Node.js, no Puppeteer, no Chrome, no JS runtime of any kind.
pip install mmdr
That's it. No system dependencies, no extra steps.
Output formats: SVG · PNG · raw RGBA pixels · NumPy array
Two backends, one package:
merman(default) — targets full parity with the official Mermaid @11.15.0 library, supports all diagram types including newer ones like kanban, architecture, and c4mermaid-rs-renderer— a lighter, faster alternative that covers the most common diagram types
CLI
mmdr ships with a command-line tool that works similarly to the official
mermaid-cli (mmdc), but
starts in milliseconds instead of seconds because there's no browser to boot.
Quick start
# render a file to SVG
mmdr -i diagram.mmd -o output.svg
# render to PNG
mmdr -i diagram.mmd -o output.png
# read from stdin, write to stdout — works great in pipelines
echo 'flowchart LR; A-->B-->C' | mmdr -i - -o -
# save the output to a file from a pipe
echo 'flowchart LR; A-->B-->C' | mmdr -i - -o diagram.svg
PNG options
mmdr -i diagram.mmd -o output.png \
--width 1200 \ # canvas width in pixels
--height 800 \ # canvas height in pixels
--background '#ffffff' # background color (transparent by default)
Backend and theme
# use the faster backend for simple diagrams
mmdr -i diagram.mmd -o output.svg --backend mermaid-rs-renderer
# classic Mermaid theme (mermaid-rs-renderer only)
mmdr -i diagram.mmd -o output.svg --backend mermaid-rs-renderer --theme classic
Batch rendering
# convert every .mmd file in a directory
for f in diagrams/*.mmd; do
mmdr -i "$f" -o "${f%.mmd}.svg"
done
# same, but PNG with a white background
for f in diagrams/*.mmd; do
mmdr -i "$f" -o "${f%.mmd}.png" --background '#ffffff'
done
Other commands
mmdr --info # render Mermaid's built-in info diagram and show its text
mmdr --version # print the mmdr version
mmdr -h # full list of options
Python API
Rendering
mmdr.render() accepts a Mermaid source string and returns a Diagram object.
The actual rendering is lazy — nothing runs until you ask for an output.
The SVG result is cached, so calling .svg() multiple times only renders once.
import mmdr
d = mmdr.render("""
flowchart TD
A[Start] --> B{Is it working?}
B -- Yes --> C[Great!]
B -- No --> D[Debug it]
D --> B
""")
SVG
svg = d.svg() # str
# write to file
with open("output.svg", "w") as f:
f.write(svg)
PNG
# default: transparent background, size determined by the diagram
png = d.png()
# with explicit size and background
png = d.png(width=1200, height=800, background="#ffffff")
with open("output.png", "wb") as f:
f.write(png)
Save — auto-detect format
d.save("output.svg") # writes SVG
d.save("output.png") # writes PNG
d.save("output.png", width=1200, background="#ffffff") # PNG with options
Raw pixels
.raw() returns the pixel buffer directly from the renderer as
(bytes, width, height). The bytes are raw RGBA8888 data —
4 bytes per pixel, row-major, top-to-bottom.
No encoding, no copying through an image library.
raw, w, h = d.raw(background="#ffffff")
print(f"image is {w}×{h} pixels, {len(raw)} bytes")
NumPy
.numpy() returns an (H, W, 4) array with dtype uint8 and RGBA channel order.
It's built on .raw() — requires only numpy, no Pillow.
arr = d.numpy()
print(arr.shape) # e.g. (480, 640, 4)
print(arr.dtype) # uint8
# drop alpha → RGB
rgb = arr[:, :, :3]
# flip upside-down
import numpy as np
flipped = np.flipud(arr)
Jupyter / IPython
Diagram implements _repr_svg_(), so notebooks render it inline
without any extra code:
import mmdr
# just evaluating this in a cell displays the diagram
mmdr.render("sequenceDiagram\n Alice->>Bob: Hello!\n Bob-->>Alice: Hi!")
Backends
mmdr.backends()
# ['merman', 'mermaid-rs-renderer']
# merman is the default — pick it explicitly if you want to be clear
d = mmdr.render("flowchart LR; A-->B", backend="merman")
# mermaid-rs-renderer for simpler diagrams where speed matters
d = mmdr.render(
"flowchart LR; A-->B-->C",
backend="mermaid-rs-renderer",
theme="classic", # "modern" (default) or "classic"
node_spacing=60.0,
rank_spacing=80.0,
aspect_ratio=(16, 9),
)
The theme, node_spacing, rank_spacing, and aspect_ratio options only
apply to mermaid-rs-renderer. The merman backend uses its own layout engine
tuned for parity with the official library.
Low-level utilities
If you already have an SVG string from another source, you can rasterize it
directly without going through render():
from mmdr import svg_to_png, svg_to_raw
svg = open("diagram.svg").read()
png = svg_to_png(svg, width=1200, background="#ffffff")
raw, w, h = svg_to_raw(svg)
Supported diagram types
| Diagram type | merman | mermaid-rs-renderer |
|---|---|---|
| flowchart / graph | ✅ | ✅ |
| sequenceDiagram | ✅ | ✅ |
| classDiagram | ✅ | ✅ |
| stateDiagram | ✅ | ✅ |
| erDiagram | ✅ | ✅ |
| pie | ✅ | ✅ |
| gantt | ✅ | ✅ |
| timeline | ✅ | ✅ |
| mindmap | ✅ | ✅ |
| gitGraph | ✅ | ✅ |
| xychart | ✅ | ✅ |
| block diagram | ✅ | ❌ |
| architecture | ✅ | ❌ |
| kanban | ✅ | ❌ |
| c4diagram | ✅ | ❌ |
| sankey | ✅ | ❌ |
| packet | ✅ | ❌ |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mmdr-0.1.0.tar.gz.
File metadata
- Download URL: mmdr-0.1.0.tar.gz
- Upload date:
- Size: 38.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6080109b5b8ee8602e7b6c91360bf9a65ad81079c912e5e88aaa9b1b2ffb477
|
|
| MD5 |
1a0bd1b7e126020011c8f9781ffb9e59
|
|
| BLAKE2b-256 |
37d29c9b5e4a64ae16eab0f781212ecc246a8d53755416d33d1c2522e3cd53de
|
File details
Details for the file mmdr-0.1.0-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: mmdr-0.1.0-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 8.3 MB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed557e90ef1541f25b67a591a98e2c2660f3fadf42a09a9f1707296ee6508a28
|
|
| MD5 |
1a77e33efe8eb0725b841cb1260d765e
|
|
| BLAKE2b-256 |
3e9759e38ed561b9fa1cac7354167c8d268add9cd8467e4af4ac098bc9a30ae9
|
File details
Details for the file mmdr-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: mmdr-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 8.2 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52af227786c44927a96dc747499e57b17aa5eaf95630521d172dba5fbc135fbb
|
|
| MD5 |
c177114aa82856c33ffa264445849d81
|
|
| BLAKE2b-256 |
85901384d595a368522142d14c9fb4630507f68836361a459051bcab4a1369f6
|
File details
Details for the file mmdr-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: mmdr-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 7.6 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
009916415274cafa195cfa7adf141ce7572131d77e72ba7dd7b2d9e8009d53c6
|
|
| MD5 |
a29ec1519d5f98d73ca6dd3016b876c9
|
|
| BLAKE2b-256 |
10d5bc32108ca1084c46a8660eaffef157a7838a16e33b6ddb881358b71ece00
|
File details
Details for the file mmdr-0.1.0-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: mmdr-0.1.0-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 7.3 MB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59195f456f2d372f0eda211f59f7f59510decc0a21ebc165b4df52b15d45ae31
|
|
| MD5 |
040d23ec161141a6ccba218cea32f481
|
|
| BLAKE2b-256 |
f97a02001f7403301280053edf28145b208384128373b3455083cd13ba67a67a
|
File details
Details for the file mmdr-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: mmdr-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 7.9 MB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dcfdd6e8bd98ab0ef533a20c24d7af43cd336d291ac9ce736f598f3f7342ee0d
|
|
| MD5 |
d2a15ce35cfe3fd7169868e48884f4fc
|
|
| BLAKE2b-256 |
e2c9ff2a1990725479d8e2c2ad8bb3b94fa07b275a7f1e530c21ab4c8728595e
|