SevyDevy

Guide · Frontend

Mermaid to SVG Explained: Rendering Diagrams at Build Time with Pele

27 min readUpdated By Saket Bhatnagar

Researched and drafted with AI, reviewed and edited by Saket Bhatnagar.

In short

  • Mermaid to SVG means turning Mermaid text, a small language for describing diagrams, into SVG, a vector image format that browsers draw directly. You can do it once, when you build your site.
  • Doing it in every reader's browser is heavy. In our test the full Mermaid 12.1.0 bundle was about 1.57 MB after gzip, a common compression for downloads. Its split-up build still pulled about 740 kB for one small flowchart.
  • Pele 1.9.0, released on 22 October 2026, is a free MIT-licensed renderer with no runtime dependencies. It turns Mermaid 12.1.0 text into SVG in Node, which runs JavaScript outside the browser, or in the browser itself.
  • Before you switch, check fidelity, security and theming. Fidelity means every diagram still parses and reads well. Pele also drops click callbacks, code that runs when a box is clicked, and ignores Mermaid's theme settings.
  • Beginners can stop after the theming section. Engineers then get our own measured speed and size numbers next to the landing page's unverified claims, a tested security table against Mermaid's securityLevel setting, and a migration checklist.

What goes wrong when every reader's browser has to draw your diagrams?

Every reader downloads a large diagram renderer and waits for it to run before any diagram appears. Rendering Mermaid to SVG once, when you build the site, moves that work off the reader's phone.

Picture a common setup. An engineering team keeps its handbook as Markdown files in Git, with about 60 Mermaid diagrams across 40 pages. The handbook is made up, but the sizes and timings below come from our own tests.

A static site generator turns the files into HTML pages, and each page loads Mermaid with a script tag. Mermaid then finds each diagram's text, works out the layout and draws it. Until that finishes, the reader sees raw text or an empty gap.

A new joiner opens the handbook on a budget Android phone over mobile data. In our test, the full Mermaid 12.1.0 bundle was 1,567,303 bytes after gzip, about 1.57 MB, before a single box is drawn.

There is a second cost. The renderer runs whatever diagram text the page holds, inside the reader's browser. If people outside the team can write diagrams, as on a wiki or a forum, that text is untrusted input.

Diagram-as-code, writing diagrams as plain text that lives next to the code, is a big reason teams like Mermaid. Diffs are readable and reviews are easy. The open question is where the text becomes a picture.

Which words do you need before rendering Mermaid to SVG?

  • Mermaid: an open-source text syntax and JavaScript library for diagrams, supported by many Markdown tools. It is the open standard here, and Pele is one implementation of it.
  • SVG (Scalable Vector Graphics): an image format made of shapes and text, written as markup that a browser draws and that CSS can style.
  • Client-side rendering: the reader's browser runs JavaScript that turns the diagram text into a picture.
  • Build-time rendering: your build machine makes the picture once, and readers get finished SVG. Doing the same on a server for each request is server-side rendering.
  • Parser: code that reads the text and builds a model, a structured list of the boxes, arrows and labels.
  • Layout: the step that decides where every box and arrow goes. It needs the width of every label.
  • DOM (Document Object Model): the browser's live model of a page. Mermaid uses it to measure text.
  • gzip: the compression most servers apply when sending files. Sizes in this guide are gzipped unless they say raw.

How does Mermaid to SVG rendering work?

Mermaid and Pele both run four steps: detect the diagram type, parse the text into a model, lay out the shapes and write the SVG. Only the layout step is hard.

Detecting the type means reading the first keyword, such as flowchart or sequenceDiagram. Parsing turns a line like A --> B into a model with two nodes and one edge. Writing SVG is plain string building once every position is known.

Layout needs label widths, because each box must fit its text. Mermaid 12.1.0 measures labels by drawing them into the page's DOM and reading their size. In our test its parse() call ran in plain Node, but render() stopped with the error document is not defined.

Pele measures text with a canvas in browsers and with a built-in width table elsewhere, according to its API docs. So the same render() call also works in Node, on a build machine with no browser.

What one render() call does

Each arrow is one step inside render(). Notice the measuring step: it is why Mermaid needs a browser's DOM, and why Pele can run in Node with a width table.

Diagram connections:

  • Mermaid text in Markdown to Detect the diagram type (diagram text)
  • Detect the diagram type to Parse into a model (type known)
  • Parse into a model to Measure label widths (labels to fit)
  • Measure label widths to Lay out boxes and arrows (label sizes)
  • Lay out boxes and arrows to Write the SVG string (positions)
  • Write the SVG string to Static HTML page (inline SVG at build time)
  • Mermaid text in Markdown: flowchart LR, then lines like A --> B
  • Detect the diagram type: detectType() reads the first keyword
  • Parse into a model: parse() returns nodes, edges and styles
  • Measure label widths: Canvas in a browser, width table in Node
  • Lay out boxes and arrows: Ranks, order, positions, routed edges
  • Write the SVG string: render() returns svg, width, height, links
  • Static HTML page: The reader's browser only draws the SVG

In Pele these steps are public functions. detectType() returns the type or null, parse() returns the model, and render() accepts either the text or that model. In our test, render(parse(text)) gave exactly the same SVG as render(text).

How Pele lays out a flowchart

Pele's docs, including its compatibility page, say only that it uses its own layout. Its layered layout source file on the main branch describes a Sugiyama-style layout, a classic method for drawing graphs whose arrows point one way.

It first reverses any arrow that closes a loop, so the graph flows in one direction. It puts each node on a rank, a row along that direction. Then it reorders each rank to reduce crossing lines and assigns positions.

That description is undocumented as of 23 October 2026 and comes from the main branch, not the 1.9.0 tag, so pin your version if the layout matters to you.

Why render Mermaid diagrams at build time instead of in the browser?

Because readers then download a finished picture instead of a renderer. The trade is that anything needing JavaScript on the page, such as click callbacks, has to go.

Think of a wedding caterer. Client-side rendering sends raw ingredients and a cook to every table. Build-time rendering cooks once in the kitchen and sends out plated food.

The ingredients are the Mermaid text, the cook is the renderer's JavaScript, the plate is the SVG and each table is a reader's browser. The kitchen is your build machine.

Where the picture breaks: a plated dish cannot reshape itself for a small table. A built SVG only scales down on a phone, unless you also build a narrow version. Colours are different, because CSS can still change them at the table.

We compared five ways to show the same small flowchart. We measured four of them in headless Chromium 153, a browser run without a window, from a local server. We summed the gzip size, at level 9, of every JavaScript file each page fetched.

What the reader downloads to see one small flowchart, measured on 23 October 2026
ApproachWhere layout runsWhat the reader downloadsLooks like Mermaid?
Mermaid 12.1.0 full bundle in the pageThe reader's browserAbout 1.57 MB of JavaScriptYes, it is Mermaid
Mermaid 12.1.0 ESM build, which loads only the code a diagram needsThe reader's browserAbout 740 kB of JavaScript in 29 filesYes
Pele 1.9.0 core plus its flowchart module in the pageThe reader's browserAbout 62 kB of JavaScript in 17 filesSame syntax, Pele's own layout and style
Pele 1.9.0 in Node at build timeYour build machineNo JavaScript, an SVG of about 3.7 kBSame syntax, Pele's own layout and style
Mermaid CLI at build timeA headless Chrome on your build machineNo JavaScript, only the SVG (size not measured)Yes

Mermaid's own SVG for that flowchart was about 33.8 kB, and 22 kB of it was an embedded style block. Pele's SVG had no style block; it points at CSS variables instead.

The Mermaid CLI is Mermaid's own build-time route. Its version 12.0.0, the latest on npm as of 23 October 2026, lists Puppeteer, a library that drives a headless Chrome, as a peer dependency. So your build machine runs a browser to make each picture.

Build-time SVG fixes three smaller problems too. The page arrives with the diagram in it, so nothing jumps when a script finishes. Readers with JavaScript off still see it.

And the same input gave identical SVG on repeated runs in our tests. A build cache keyed on the diagram's text can therefore skip diagrams that did not change.

The costs are real. Pele's static SVG carries no click callbacks. It cannot re-lay itself out for a narrow phone, which Pele's mount() can do in the browser. And box sizes in Node come from a width table, not your page font.

What does Pele 1.9 support, and what does it leave out?

Pele's landing page and README say it supports every diagram type built into Mermaid 12.1.0. It draws them with its own layout and style, and in our tests it ignored Mermaid settings that only change how diagrams look.

We checked the coverage claim two ways. First, the diagram ids registered in Mermaid 12.1.0's bundle and in Pele's detector list are the same 37, from flowchart-v2 to railroadPeg. Mermaid 12.2.0 registers the same 37.

Second, we rendered 35 sample diagrams in Chromium, one per type plus two flowchart variants, through both libraries. All 35 rendered in both. Most samples came from Pele's own examples page, so this tests coverage, not edge cases.

The maintainer put the scope plainly on Hacker News: Pele follows Mermaid's syntax, not its layout. The same text gives a recognisably different picture, which is why you review diagrams before switching.

Mermaid diagrams can carry settings in frontmatter, a block between two --- lines at the top, or in an init directive, a line that starts with %%{init:.

What Pele 1.9.0 did with Mermaid features in our tests
Mermaid inputMermaid 12.1.0Pele 1.9.0
A ZenUML diagram, a type that needs a separate pluginNot detected without the pluginunsupported-diagram error
theme or themeVariables in frontmatter, or an init directive asking for the dark themeAccepted as colour settingsIgnored: identical SVG
layout: elk or look: handDrawn in frontmatterAccepted as layout and style settingsIgnored: identical SVG
An animated edge, e1@{ animate: true }AcceptedParsed, then drawn as a plain line
b, i, u and br tags in a labelKept as HTML inside a foreignObjectTurned into SVG bold, italic, underline and line breaks
img or a tags in a labelKept after sanitisingDropped
accTitle and accDescr linesAcceptedSVG title and desc, with ids pele-title and pele-desc by default

A foreignObject is an SVG element that holds ordinary HTML. None of the 56 diagrams we rendered with Pele contained one. Its docs mention one exception: math markup your app supplies as HTML.

One trap matters for build scripts. With render(), a diagram that has accTitle or accDescr gets the ids pele-title or pele-desc. Two such diagrams on one page then share ids, so pass a different idPrefix to each.

mount() does not have this problem, because it gives each diagram its own prefix. Our script numbers diagrams per file, so if a page joins several files, put the file name in the prefix too.

Pele also ships smaller entry points. Importing pele/core with one diagram module keeps the bundle small, and pele/lazy loads each type on first use. A type you did not register fails with unsupported-diagram.

How do you render Mermaid to SVG in a build script?

Install an exact version, read each Markdown file, swap every mermaid code block for the SVG that render() returns, and fail the build on any PeleError, Pele's error type.

Pin it exactly, because Pele shipped nine minor versions in 16 days. Run npm install --save-exact [email protected], which needs Node 20 or later. Do not install [email protected], the unrelated 2020 package.

javascript
// build-diagrams.mjs: replace mermaid code blocks in a Markdown file with inline SVG.
// Tested with pele 1.9.0 on Node 22. Run: node build-diagrams.mjs docs/page.md
import { readFileSync, writeFileSync } from 'node:fs';
import { render, PeleError } from 'pele';

const file = process.argv[2];
const markdown = readFileSync(file, 'utf8');
let n = 0;

const html = markdown.replace(/```mermaid\n([\s\S]*?)```/g, (block, source) => {
  n += 1;
  try {
    // idPrefix keeps ids unique when several diagrams share one page
    const { svg } = render(source, { idPrefix: `d${n}` });
    return `<figure class="diagram">${svg}</figure>`;
  } catch (err) {
    if (!(err instanceof PeleError)) throw err;
    console.error(`${file} diagram ${n}: ${err.code} at line ${err.line}`);
    process.exitCode = 1; // fail the build, keep the source block
    return block;
  }
});

writeFileSync(file.replace(/\.md$/, '.rendered.md'), html);
console.log(`${file}: ${n} diagrams found`);

What just happened? The regular expression, a text pattern, finds each fenced mermaid block. render() returns the SVG as a string, and the script pastes it into the Markdown as raw HTML. Your Markdown tool must allow raw HTML, and some turn it off by default.

markdown-it, a common Markdown parser, escapes raw HTML unless you pass html: true. In our test with markdown-it 14.1.0, the default turned the SVG into visible text.

A broken diagram does not stop the loop. The script prints the file, the diagram number, the error code and the line. It keeps the original block and sets exit code 1, so the build fails.

The pattern is deliberately simple. It expects Unix line endings and fences that start at the left margin, so extend it if your files use Windows line endings or indented fences.

To check it worked, run it on a file with four diagrams, one of them broken. These are the commands and the output we saw on Linux with pele 1.9.0.

bash
node build-diagrams.mjs docs/architecture.md
# docs/architecture.md diagram 3: syntax at line 2
# docs/architecture.md: 4 diagrams found

echo $?
# 1   (the broken diagram fails the build)

grep -o '<svg' docs/architecture.rendered.md | wc -l
# 3   (one SVG per good diagram)

How do Pele's error codes help you fail a build?

Pele reports a bad diagram as a PeleError with one of four codes, so a build can react to each kind. Syntax errors also carry a line, a column and a snippet showing where parsing stopped.

PeleError codes in Pele 1.9.0, each triggered in our tests
CodeWhat triggered itMessage we saw
unsupported-diagramText with no known first keyword, a ZenUML diagram, or a type not registered with pele/coreNo diagram type detected for the given text.
syntaxA[Start --> B[End], a box that never closesParse error on line 2 ... got 'SQS', with column 16 in the error
semanticA Gantt task dated 2026-13-45, or a gitGraph checkout of a branch never createdInvalid date:2026-13-45
limitSource over 50,000 characters, more than 5,000 edges, or SVG over 4,000,000 charactersDiagram source is longer than the limit of 50000 characters.

The syntax messages follow the format of Mermaid's own parser, down to the token names. For the same broken box, Mermaid 12.1.0 listed more expected tokens but ended with the same got 'SQS'.

Some odd input passes both. An XY chart with three bars for two labels rendered without error in both libraries. An error-free build does not prove a chart is right.

In the browser, mount() shows the error text inside the element instead of a picture. Pele's security page says to display error messages with textContent, which inserts plain characters and never markup, because the messages can contain diagram text.

How does Pele's security compare with Mermaid's securityLevel?

Pele has one policy for every diagram, tuned with a few render options rather than named levels. It is close to Mermaid's default strict mode, and stricter in places. Mermaid instead offers securityLevel, a switch that a site sets once for all its diagrams.

Mermaid's levels are strict, the default, antiscript, loose and sandbox, which draws inside a sandboxed iframe. A diagram cannot raise its own level: in our test, init and frontmatter requests for loose were ignored.

The same inputs through three renderers, on flowcharts with HTML labels on, run on 23 October 2026 with harmless test flags
Diagram inputMermaid 12.1.0 strict (default)Mermaid 12.1.0 loosePele 1.9.0
click A callback, naming a JavaScript functionNot runRan when clickedIgnored, no link
click A with a javascript: URLLink kept, URL removedjavascript: URL keptDropped, even with javascript added to the linkSchemes allow-list
click A with an https URLLink keptLink keptLink kept, with rel noopener so the opened page cannot control yours
A label with b tags and an img tag carrying an onerror handlerb and img kept, handler removedb and img kept, handler removedBold SVG text, img dropped
A label with a script tagScript removedScript removedScript removed, its text shown as plain text
Size limits50,000 characters, 500 edgesSame at every level: separate settings50,000 characters, 5,000 edges, 4,000,000 characters of SVG

As of 23 October 2026, Mermaid's docs say strict mode encodes HTML tags. In 12.1.0 flowcharts with HTML labels, the default, we saw something different. Strict mode kept b, i, u, img and a tags, after removing scripts, event handlers and javascript: link URLs.

Mermaid 12.1.0's source explains why. With HTML labels on, it treats strict like antiscript: it removes scripts and runs a sanitizer, but does not encode tags. With htmlLabels set to false, the same tags showed as plain text.

That matters for privacy. An img tag left in a strict-mode label made the browser request its URL in our test, so a diagram can still load a tracking image. Pele drops img tags in labels.

Pele does draw images from Mermaid's img: shape syntax over http or https, and those also make requests. For diagrams from strangers, pass images: false and links: false.

Links follow an allow-list. Pele's security page says it allows http, https, mailto, tel and relative links by default, and always blocks javascript:, data: and vbscript:. In our tests it kept https and relative links and dropped ftp and //host links.

Renderers are attack surface. As of 23 October 2026, Mermaid's GitHub security page counts 14 advisories, including infinite-loop bugs in Gantt and XY charts. Others include CSS and HTML injection through classDef, Mermaid's way to name a reusable style, and an XSS bug in architecture diagrams.

Pele's repository lists none, but its first release was only 17 days ago. No published advisories is not proof of safety.

Choosing a policy by who writes the diagrams

Start at the question. Trusted text only needs a failing build; untrusted text needs every box on the second path, because Pele limits size but not time.

Diagram connections:

  • Who writes the diagrams? to Your team, reviewed in Git (Our team)
  • Who writes the diagrams? to Outside users (Outside users)
  • Your team, reviewed in Git to Insert the SVG (build output)
  • Outside users to Keep default limits
  • Keep default limits to Turn off links and images
  • Turn off links and images to Render in a worker
  • Render in a worker to Show errors as text (on failure)
  • Render in a worker to Insert the SVG (on success)
  • Who writes the diagrams?: Decide before choosing where to render
  • Your team, reviewed in Git: Render at build time and fail on errors
  • Outside users: Wiki pages, comments, uploads
  • Keep default limits: 50,000 chars, 5,000 edges, 4,000,000 chars out
  • Turn off links and images: links: false and images: false
  • Render in a worker: Stop it after a time budget you choose
  • Show errors as text: Use textContent, never innerHTML
  • Insert the SVG: mount() also takes an optional sanitize hook

Pele's security page also lists what stays your job. Icons and math markup that your app supplies go in unfiltered, and diagram authors should never set the render options or config.

How does theming work when Mermaid diagrams become SVG?

Pele takes its default colours from CSS variables, such as --pele-surface for node fill, so your stylesheet decides them. Mermaid theme settings inside the diagram text had no effect in our tests.

In Chromium we set --pele-surface on the element around a rendered diagram. The node fill changed from rgb(243, 243, 243) to the new colour with no re-render. Dark mode becomes a stylesheet change.

css
.pele {
  --pele-bg: #ffffff;
  --pele-fg: #1f1f1f;
  --pele-surface: #f3f3f3;
  --pele-accent: #5b7bd5;
}

@media (prefers-color-scheme: dark) {
  .pele {
    --pele-bg: #1c1b1a;
    --pele-fg: #e6e4d9;
    --pele-surface: #282726;
    --pele-accent: #8ba9f0;
  }
}

With this stylesheet and Chromium set to dark mode, the same SVG's node fill became rgb(40, 39, 38) in our test. The variable names and light defaults come from Pele's theming page.

Colours written inside a diagram, with style or classDef, are fixed. In our test a classDef fill of red stayed red after the theme changed, so use those for meaning, not decoration.

Fonts need more care. Pele sizes boxes from label widths, so the measuring font should match the display font. In Chromium, render() with a serif font gave a 973 pixel wide flowchart, against 1,026 for the default.

In Node, naming a different fontFamily did not change the width for us, because the built-in table was used. If your site font is much wider, pass a measurer, an object whose width() function returns each label's width.

Narrow screens are the other gap. In a container under 640 pixels, mount() turned our five-step flowchart from a 678 by 64 strip into a 143 by 448 column. render() with maxWidth: 400 did the same in Node.

So a build can make a phone version of a wide diagram too, and the page's CSS can pick one by screen width.

Beginners can stop here. You know what Mermaid to SVG means, why build time helps and what to check. The rest is for engineers: the speed claims, a migration checklist and the interview answer.

Is Pele really 500 times faster than Mermaid.js?

Not as one number you can rely on. As of 23 October 2026, the landing page says up to 500 times faster and gives no method. Our own test found about 29 to 737 times.

The page's table lists 230 kB against 1.6 MB gzipped, and 0.05 to 0.3 ms against 6 to 82 ms per render. It names no hardware, diagrams or method, so treat these as the project's unverified claims.

Those ranges do not say which diagram gave which time, so they can neither confirm nor rule out 500 times. In our tests two types, mindmap and kanban, did beat 500 times, but the median was about 173 times. Read up to 500 times as a best case.

The size figure matched an older release. All sizes here are GNU gzip at level 9. Pele 1.0.1's pele.js gzips to 230,250 bytes, the landing page number. The same file grew in each release we checked: 250 kB at 1.4.0, 251 kB at 1.6.0, 259 kB at 1.8.0 and 262 kB at 1.9.0.

Pele 1.9.0's browser bundle, pele.global.js, gzips to 262,733 bytes, about 263 kB. Mermaid 12.1.0's mermaid.min.js gzips to about 1.57 MB, so the full bundles are about 6 times apart, as the page says.

How we measured render time

We rendered 35 diagrams in headless Chromium 153 on a 2-vCPU Linux machine, with Pele 1.9.0 and Mermaid 12.1.0 loaded in the same page. Each diagram was rendered once first, to warm up.

Pele's time is the mean of 200 calls and Mermaid's the mean of 10 awaited calls. We took the median of three fresh page loads for each diagram.

Our warm render times on 23 October 2026, in milliseconds per diagram
DiagramPele 1.9.0Mermaid 12.1.0Ratio
Venn0.2747.929x
Gantt0.0859.1107x
State0.60488.6147x
Flowchart0.34461.1178x
Sequence0.12625.6203x
Mindmap0.08246.5567x
Kanban0.02518.2727x
All 35 diagrams0.004 to 0.6043.0 to 88.629x to 737x, median 173x

So Pele was far faster on every diagram we tried, usually by a hundred times or more. Sub-millisecond timings moved by two to four times between page loads on 2-vCPU machines, so read the ratios as rough.

At build time, speed matters less than it sounds. Pele in Node took about 0.4 ms per diagram once warm, and about 120 ms for the first pass over all 35. A docs build renders each diagram once.

How do you check Pele's output against Mermaid before switching?

Run every diagram you own through both renderers, list any that succeed in one and fail in the other, then review the pictures that matter most.

  1. Collect every diagram

    Extract every mermaid block from your repository into its own file, and record the source file and line it came from.

  2. Pin both versions

    Install [email protected] and [email protected] as exact versions, so a new release cannot change results halfway through.

  3. Run detectType first

    Call Pele's detectType() on each diagram. A null means a type Pele does not know, such as ZenUML, and needs a decision.

  4. Render with both

    Render each diagram with Pele in Node and with Mermaid in a headless browser. List every diagram that fails in only one of them.

  5. Search for ignored features

    Search the diagrams for click, securityLevel, theme, themeVariables, layout: elk, look: handDrawn and animate. Each one renders differently or not at all in Pele.

  6. Compare the pictures

    Review your busiest diagrams side by side. Pele's playground has a Compare mode, which the maintainer pointed to in the launch thread.

  7. Give each diagram an idPrefix

    When you call render(), pass a unique idPrefix for every diagram on a page, so accessible titles and descriptions never share ids.

  8. Decide the failure rule

    Choose what a broken diagram becomes, such as the source block plus a failed build, and write that rule into the build script.

How do you explain Mermaid to SVG rendering in a system design interview?

Treat it as a worked example of moving work from the client to the build, and say the trade-offs out loud. Each step below is one sentence you can say.

  1. State the problem

    Shipping a diagram renderer to every reader costs download size and time, and it runs diagram text inside each browser.

  2. Name the pipeline

    Rendering is detect, parse, lay out and write SVG, and only layout needs text measurement.

  3. Move the work

    Render once at build time, cache by the diagram's text and ship static SVG with no JavaScript.

  4. Name the costs

    You lose click callbacks and per-device layout, so build a narrow version or keep a browser renderer for editors.

  5. Secure the input

    For untrusted diagrams, keep size limits, turn off links and images, and render in a worker with a time budget.

  6. Check fidelity

    Run every existing diagram through the old and new renderers and review the differences before switching.

Questions people ask

Is Pele a fork of Mermaid?
No. Pele is a separate renderer that reads Mermaid's syntax and draws it with its own layout and style. Its README says its parsers are tested against Mermaid's parser specs and with differential fuzzing, which feeds both parsers the same random input and compares the results. Those specs and their grammar files come from Mermaid under the MIT licence. The output is not meant to match Mermaid pixel for pixel.
Can Mermaid itself render SVG in Node without a browser?
Not with its normal render call. In our test with Mermaid 12.1.0, parse() worked in plain Node, but render() failed with document is not defined, because Mermaid measures text through the browser's DOM. The official Mermaid CLI runs Mermaid inside a headless Chrome driven by Puppeteer. That works and matches Mermaid exactly, but your build machine then needs a browser.
Will my existing Mermaid diagrams look the same in Pele?
They should parse, but they will not look identical. Pele follows Mermaid 12.1.0 syntax with its own layout and visual style, and it ignores theme settings, the ELK layout choice and the hand-drawn look. Review your busiest diagrams side by side before switching. Opinions on the launch thread varied, from preferring Pele's layouts to seeing little difference, so judge your own diagrams.
Does build-time SVG work for diagrams that users type into my app?
Not on its own, because you cannot rebuild the site for every comment. Render those on your server or in the browser instead. Treat the text as untrusted: keep Pele's size limits, set links: false and images: false, run the render in a worker you can stop, and show error messages with textContent. Pele's security page lists these steps.
Which Pele version should I install?
Install an exact version and upgrade on purpose. We tested 1.9.0, the latest on 23 October 2026, and Pele published 16 releases in its first 16 days. Use npm install --save-exact [email protected] and check npm view pele versions before upgrading. Avoid [email protected], an unrelated package from 2020 that shares the name.
Is the SVG from Pele accessible to screen readers?
Partly, and you can help it. Pele's SVG carries the role graphics-document and an aria-roledescription such as flowchart. If the diagram has accTitle and accDescr lines, Pele adds an SVG title and description and links them to the image. Write those two lines in every important diagram, and when you use render(), give each diagram on a page a unique idPrefix.
How big a speed-up should I expect from Pele?
In our warm tests in headless Chromium, Pele rendered between about 29 and 737 times faster than Mermaid 12.1.0, with a median of 173 times. The landing page's up to 500 times has no published method. At build time the gain matters less, because each diagram renders once. For readers, the bigger win is downloading no renderer at all.

Sources and further reading

Practise this with Lala

Practise