lecture.studio

Mermaid diagrams in Marp: a working engine for HTML and PDF

Marp does not render Mermaid; a mermaid fence is shown as code. Two routes work: pre-render the diagram to an SVG and include it as an image, which is portable to every Marp tool, or give marp-cli an engine file that turns mermaid fences into diagrams at export time, which produces HTML, PDF and PNG with the diagram drawn. The engine below was tested with marp-cli 4.5 in September 2026.

This guide gives both routes with the exact files, says what each needs, and notes what the VS Code extension and other tools do with the same deck.

Route 1: pre-render to SVG

Install Mermaid's command line once and render each diagram to a file:

npm install -g @mermaid-js/mermaid-cli
mmdc -i scheduler.mmd -o assets/scheduler.svg

Then in the deck:

![w:900](assets/scheduler.svg)

The SVG is a normal image: it renders in the VS Code preview, in marp-cli, in Lecture Studio, and in the online editor, and it goes into the PDF without a network connection. The cost is a build step when the diagram changes, and the .mmd source lives next to the deck instead of inside it. For a course, a make diagrams target that renders every .mmd in assets/ keeps this painless.

Route 2: a marp-cli engine

An engine file lets marp-cli use extra markdown-it plugins. This one renders mermaid fences as <pre class="mermaid"> and appends a script that loads Mermaid from a CDN and runs it:

// mermaid-engine.mjs
export default ({ marp }) => marp.use((md) => {
  const fence = md.renderer.rules.fence;
  md.renderer.rules.fence = (tokens, i, opts, env, self) => {
    const t = tokens[i];
    if (t.info.trim() === "mermaid") return `<pre class="mermaid">${md.utils.escapeHtml(t.content)}</pre>`;
    return fence(tokens, i, opts, env, self);
  };
  md.core.ruler.push("mermaid_script", (state) => {
    const t = new state.Token("html_block", "", 0);
    t.content = `<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs"; mermaid.initialize({ startOnLoad: false }); await mermaid.run({ querySelector: ".mermaid" });</script>\n`;
    state.tokens.push(t);
  });
});

Use it with --engine and --html (the script tag needs HTML enabled):

marp --engine ./mermaid-engine.mjs --html deck.md            # HTML
marp --engine ./mermaid-engine.mjs --html deck.md --pdf      # PDF, diagram drawn
marp --engine ./mermaid-engine.mjs --html deck.md --images png

In the deck:

```mermaid
flowchart LR
  A[Ready] --> B[Running] --> C[Waiting] --> A
```

The PDF and PNG exports run the script inside marp-cli's browser before capturing, so the diagram is drawn. It needs a network connection at export time for the CDN; pin the Mermaid version in the URL so the output does not change under you. The theme's pre styling applies to the <pre class="mermaid"> element; add section pre.mermaid { background: none; border: 0; } to the theme if the diagram gets a code-block box.

What each tool does

Tool Route 1 (SVG) Route 2 (engine)
marp-cli yes yes, with --engine and --html
VS Code extension yes no engine option; fences show as code
Lecture Studio yes fences show as code
Online editor on this site yes (a public SVG URL) no

For a deck that several tools must render, route 1. For a course built with marp-cli in a script or in CI, route 2 keeps the diagram source in the slide.

Diagrams that fit a slide

Mermaid draws for a page, not a projector. Keep a diagram to a dozen nodes, use flowchart LR for wide slides, set %%{init: {"theme": "neutral"}}%% for a projector-friendly palette, and size the result with w: so it fills the slide's width. A diagram the back row cannot read is a diagram to split in two.

FAQ

Does Marp support Mermaid?

Not natively. Pre-render the diagram to SVG and include it as an image, or use a marp-cli engine that renders mermaid fences at export time.

How do I get Mermaid diagrams into a Marp PDF?

Either route works: an SVG image goes into the PDF like any image; the engine route draws the diagram inside marp-cli's browser before the PDF is captured (tested with marp-cli 4.5).

Does Mermaid work in the Marp VS Code extension?

Only as a pre-rendered SVG image. The extension has no engine option, so mermaid fences appear as code in its preview and exports.

Where do I put the engine file?

Anywhere; pass its path with --engine. A marp.config.js with engine set avoids retyping the flag.