mdbook-pele
mdBook preprocessor that renders Mermaid diagrams with Pele.
Pele is a fast, small (~230 kB gzipped), zero-dependency Mermaid → SVG renderer that themes via CSS variables. It supports every diagram type in Mermaid 12.1.0 and is used by Obsidian.
Why Pele?
Compared to the classic mdbook-mermaid (client-side mermaid.js):
| Pele | mermaid.js | |
|---|---|---|
| Bundle size (gzip) | ~230 kB | ~1.6 MB |
| Render time | 0.05–0.3 ms | 6–82 ms |
| Dependencies | 0 | 23 |
| Theming | CSS variables | theme config |
| Responsive layout | adapts layout | scales |
Quick example
flowchart TD
A[Mermaid text] --> B{Flowchart?}
B -- Yes --> C[Pele]
B -- No --> D[Mermaid]
C --> E([SVG])
D --> E
What’s in this book
- Getting Started — installing the preprocessor and setting it up in a book
- Usage — writing diagrams, and what the preprocessor does to your Markdown
- Theming — how diagrams follow mdBook themes, and how to customize them
- Supported Diagram Types — every diagram type Pele can render
- Troubleshooting — common problems and fixes
Getting Started
Prerequisites
- mdBook 0.4 or later (the preprocessor talks the standard preprocessor protocol)
- A book with a
book.toml
Install the preprocessor
Install a prebuilt binary with cargo-binstall:
cargo binstall mdbook-pele
Or build it from crates.io:
cargo install mdbook-pele
Prebuilt binaries for Linux, macOS and Windows can also be downloaded from GitHub Releases.
Set up your book
Run this in your book directory (the directory containing book.toml):
mdbook-pele install
This does two things:
- Writes the browser-side assets next to
book.toml:pele.global.js— the Pele runtimepele-init.js— mounts every diagram on page loadpele.css— maps Pele’s colors onto the active mdBook theme
- Updates
book.tomlwith:
[preprocessor.pele]
command = "mdbook-pele"
[output.html]
additional-js = ["pele.global.js", "pele-init.js"]
additional-css = ["pele.css"]
The command can be re-run safely: it never adds duplicate entries to book.toml. Be careful though — it will overwrite the asset files (pele.global.js, pele-init.js, pele.css), so re-run it only when you actually want to refresh them; customizations like theming overrides live in your own CSS files, not these.
Build
mdbook build
# or, for live preview while writing:
mdbook serve
Any fenced ```mermaid block is now rendered as an SVG by Pele. Try one:
pie title Diagrams rendered after install
"With Pele" : 100
Manual setup (without install)
You can skip the install command and configure everything by hand:
- Copy
src/bin/assets/from the repository (pele.global.js,pele-init.js,pele.css) into your book directory. - Add the
[preprocessor.pele]and[output.html]blocks shown above tobook.toml.
Upgrading
Reinstall the binary (cargo binstall mdbook-pele, cargo install mdbook-pele, or download a new release) and re-run mdbook-pele install to refresh the bundled assets. The preprocessor is version-checked against mdBook on every build: a mismatch between the mdBook version it was built against and the one running it prints a warning.
Usage
Writing diagrams
Write ordinary Mermaid fenced code blocks anywhere in a chapter:
```mermaid
flowchart TD
A[Mermaid text] --> B{Flowchart?}
B -- Yes --> C[Pele]
B -- No --> D[Mermaid]
C --> E([SVG])
D --> E
```
The same syntax the Mermaid docs describe works as usual — at build time the fenced block becomes:
<pre class="mermaid">...</pre>
and the bundled pele-init.js calls pele.mount() on each pre.mermaid element when the page loads.
What gets transformed
- Fenced code blocks with the info string
mermaidare replaced. Regular fenced blocks in other languages, indented code blocks, and inline code are left untouched. - The Mermaid source is HTML-escaped (
<,>,&,"become entities) so it survives embedding in<pre>markup — useful for things like<<interface>>in class diagrams. - CRLF line endings inside a diagram are normalized to LF.
- Blocks delimited with more than three backticks work exactly like the basic form, so you can write documents that themselves contain triple-backtick fences without breaking the diagram.
Escaping only affects characters that would break HTML embedding; Mermaid decodes standard entities itself, so arrow labels like A --> B still render as -->. Diagrams may also start with Mermaid front matter (title, config) and use %%{init: ...}%% directives and %% comments as usual — Pele handles them at parse time.
Renderer support
The preprocessor only supports the html renderer. If mdbook build is invoked with another renderer (pdf, markdown, epub, …), the preprocessor is skipped for it and the untouched Markdown passes through. For the default HTML build this never comes up.
Example: a class diagram with angle brackets
```mermaid
classDiagram
class PingUploader {
<<interface>>
+Upload() UploadResult
}
```
Renders as (the <<interface>> survives because of the escaping step):
classDiagram
class PingUploader {
<<interface>>
+Upload() UploadResult
}
For a tour of every supported diagram type, see Supported Diagram Types.
Theming
Following the book theme out of the box
pele.css maps Pele’s CSS variables onto mdBook’s own theme variables, so diagrams follow whatever theme the reader picked — Light, Rust, Coal, Navy, or Ayu — with no extra setup:
pre.mermaid,
.pele {
--pele-bg: var(--bg);
--pele-fg: var(--fg);
--pele-line: var(--fg);
--pele-muted: var(--fg);
--pele-surface: var(--quote-bg);
--pele-surface-alt: var(--quote-border);
--pele-border: var(--theme-popup-border);
--pele-accent: var(--links);
}
It also resets mdBook’s default <pre> styling (background, border, monospace font) inside diagrams so Pele measures labels with the book’s font.
The install command prepends pele.css to additional-css, so any stylesheet you add to additional-css after it (or any override in theme/css/chrome.css) takes precedence over its mappings.
Overriding individual colors
To change how diagrams look in every theme, override a variable in your book CSS:
pre.mermaid {
--pele-accent: #7aa2f7;
}
To scope an override to one theme, hang it off the theme class mdBook puts on <html>:
.coal pre.mermaid,
.navy pre.mermaid {
--pele-surface: #1d2129;
}
If a variable is not overridden it falls back to the mdBook variable above, so you only need to set what you want to change.
Full variable reference
See pele.run/theming for the complete list of Pele theme variables (--pele-node, --pele-edge, --pele-cN palette slots, and so on) and what each controls.
Notes on backgrounds
--pele-bg must be an actual page color (not white or transparent): flowchart edge labels draw a knockout rectangle with it so Yes/No labels sit cleanly on top of the arrows. The default mapping uses var(--bg), which is correct per theme; if you set a custom page background for a theme, mirror it in --pele-bg.
Supported Diagram Types
Pele ships with parsers for every diagram type in Mermaid 12.1.0. Detection is based on the first line of the diagram, so use the exact keywords below as the first token of your block.
Core diagram types
| Keyword | Diagram |
|---|---|
graph, flowchart | Flowchart (v2 layout) |
flowchart-elk | Flowchart with the ELK layout engine |
sequenceDiagram | Sequence diagram |
classDiagram | Class diagram |
stateDiagram | State diagram (v2) |
erDiagram | Entity-relationship diagram |
gantt | Gantt chart |
pie | Pie chart |
gitGraph | Git graph |
journey | User journey diagram |
timeline | Timeline |
mindmap | Mindmap |
quadrantChart | Quadrant chart |
requirementDiagram | Requirements diagram |
kanban | Kanban board |
sankey-beta / sankey | Sankey diagram |
xychart-beta / xychart | XY chart |
block-beta / block | Block diagram |
packet-beta / packet | Packet diagram |
architecture | Architecture diagram |
info | Info diagram |
treemap | Treemap |
ishikawa | Ishikawa (fishbone) diagram |
eventmodeling | Event modeling diagram |
Extended and beta types
| Keyword | Diagram |
|---|---|
C4Context, C4Container, C4Component, C4Dynamic, C4Deployment | C4 (architecture) diagrams |
agentflow-beta | Agent flow |
swimlane-beta | Swimlane |
treeView-beta | Tree view |
radar-beta | Radar chart |
venn-beta | Venn diagram |
wardley-beta | Wardley map |
cynefin-beta | Cynefin framework diagram |
usecase-beta | Use case diagram |
railroad-beta, railroad-ebnf-beta, railroad-abnf-beta, railroad-peg-beta | Railroad / syntax diagrams |
Behavior on unknown input
- If the first line does not match any known type, Pele falls back to parsing the text as ordinary Mermaid flowchart syntax (
graph/flowchart). - Syntax errors raise a
PeleErrorthat reports the offending line, column, and a snippet pointing at the problem; in the browser this appears in the console and the diagram element is left as-is rather than replacing the page with a broken render.
Examples
A few of the more distinctive types:
mindmap
root((Pele))
Fast
Small
Mermaid compatible
Flowcharts
Sequence diagrams
gitGraph commit id: "a" commit id: "b" branch feature commit id: "c" checkout main merge feature
journey
title Rendering a book diagram
section Build
mdbook runs preprocessor: 5: Me
Preprocessor rewrites block: 4: Me
section Read
Browser loads page: 3: Reader
Pele renders SVG: 5: Reader
Troubleshooting
Diagrams show as plain code blocks
Symptom: the fenced block renders as a normal code block in the HTML.
Checklist:
- Is
[preprocessor.pele]present inbook.toml? (Re-runmdbook-pele install.) - Is the info string exactly
mermaid(lowercase)? The preprocessor matches the fenced block info string literally. - Did you rebuild after installing? A stale
book/output directory can hide the change —mdbook buildregenerates it.
“Pele is not loaded” in the console
pele-init.js ran but pele.global.js did not load. Check that:
additional-js = ["pele.global.js", "pele-init.js"]is in[output.html].- Both files exist next to
book.toml. - Your book uses a custom template that includes mdBook’s global JS injection; the assets are registered through mdBook’s standard mechanism, so custom
index.hbsoverrides may need updating.
“Pele failed to render diagram” in the console
The diagram syntax is rejected by Pele’s parser. The error message includes the line, column, and a snippet of the offending text.
- Compare the first line with the keywords in Supported Diagram Types; detection is done on the first line’s first token.
- Beta diagram types require their explicit keyword (
venn-beta, notvenn). - Check YAML front matter inside diagrams — invalid YAML produces a syntax error before parsing starts.
Diagram colors look wrong in one theme
- Verify
pele.cssis inadditional-css— it is what maps Pele variables onto the active mdBook theme. - If you overrode variables, remember the fallback chain: your override wins only where you set it; otherwise it falls back to
var(--bg),var(--fg), and friends. - If you use a dark theme with a custom page background, also set
--pele-bgto the same color — see Theming.
Diagram is larger than its container
Large diagrams scroll and support pan/zoom automatically. If you want different constraint behavior, target pre.mermaid in your own CSS (max-width, centering, and so on) — Pele adapts the layout to the width it is given.
Version warning at build time
Warning: The pele plugin was built against version X of mdbook, but we're being called from version Y
Re-install mdbook-pele (or update mdBook) so versions line up. This is a warning only; the preprocessor still runs.
Anything else
- Search the GitHub issues or open one.
- General Mermaid syntax questions are best asked against the Mermaid docs — Pele aims for Mermaid 12.1.0 compatibility.