← Blog

2026.10.19 · 4 min · javascript · svg · css

Pele: Mermaid text in, SVG out, no browser.

Pele is Obsidian's MIT library that takes Mermaid syntax and returns an SVG string, with zero runtime dependencies and colours as CSS variables. Why rendering Mermaid usually means headless Chrome, what Pele changes, and the layout catch. As of 2026.10.

A Mermaid diagram is just text: flowchart LR, A --> B, and your README or notes app draws the boxes. Rendering that text yourself, in a build step or on a server, has usually meant starting a browser, because Mermaid measures text in a real page. Pele, a new MIT library from Obsidian, takes the same syntax and hands back an SVG string. No browser is needed to render it.

Watch the 60-second version on Instagram.

Why Mermaid needs a browser

Mermaid parses anywhere, but laying out a diagram means knowing how wide each label is, and Mermaid gets that from browser APIs like getBBox(). jsdom alone fails at this. So Mermaid's official CLI declares puppeteer as a peer dependency and renders through headless Chrome.

MERMAID-CLIflowchartA --> BHEADLESS CHROMEgetBBox().SVGPEER DEP · PUPPETEERPELEflowchartA --> Brender().SVG0 RUNTIME DEPS · NO BROWSERFIG. 01 / THROUGH A BROWSER, OR A FUNCTION CALL

Pele skips that machine. Its API is one function: render(text) returns { svg }. In the browser, mount(el, text) renders into an element and fits the diagram to its container. The npm package (1.6.0) lists zero runtime dependencies.

diagram.js
import { render } from 'pele';
const { svg } = render(`flowchart LR
  A[Mermaid text] --> B[SVG]`);

The docs never say "Node" or "SSR" outright. A function that returns a string and depends on nothing strongly implies it runs outside a browser, but I haven't tested it on a server, and neither has anything I can cite.

What it supports

Pele supports "every diagram type built into Mermaid 12.1.0" and follows Mermaid's syntax; its parsers are tested against Mermaid's own parser specs. Mermaid itself is now on 12.2.0, while Pele targets 12.1.0 syntax. Pele's examples use flowchart; graph TD is valid Mermaid too, but I'd stick to flowchart with it.

The site also publishes numbers, compared with Mermaid:

PeleMermaid
Size, gzip230 kB1.6 MB
Render time0.05–0.3 ms6–82 ms
Direct deps023

These are pele.run's figures. The page gives no method and the repo publishes no benchmark results, so I can't tell you whether they were measured with or without a DOM. Treat them as the author's claim.

Themes are CSS variables

Mermaid's themeVariables don't apply. Instead you style .pele with custom properties: --pele-bg, --pele-fg, --pele-muted, --pele-line, --pele-surface, --pele-surface-alt, --pele-border, --pele-accent, --pele-font and --pele-radius. In the docs' words, "Color changes apply without re-rendering".

theme.css
.pele { --pele-bg: #fff; --pele-fg: #0a0a0a; }
.pele {--pele-bg:--pele-fg:}white;black;navy;white;ABABSAME SVGVALUES CHANGE · NO NEW render()RE-RENDERS · 0FIG. 02 / SAME SVG, NEW VALUES

The values in the figure are mine, for illustration. The point is the counter: a dark mode toggle is a CSS change, not another render() call.

What people get wrong

  • "It's a drop-in Mermaid renderer." It follows the syntax, not the layout. The compatibility page says node positions, spacing and edge paths differ from Mermaid. kepano put it on HN as Pele "only follow[s] its syntax not its layout".
  • "My Mermaid theme config carries over." It's ignored. Restyle with the --pele-* variables.
  • "It renders in a fraction of a millisecond." That's pele.run's number, self-reported with no stated method.
  • "pele on npm has been around since 2020." The name was reused: the 2020 1.0.0 was an unrelated package. The current releases started on 2026.10.06 (1.0.1), and 1.6.0 shipped on 2026.10.17. The HN post has 574 points.

On a client project I'd use Pele for diagrams in docs and build output where nobody compares it with Mermaid's layout, and keep Mermaid where a diagram has to look exactly like Mermaid draws it.

The short version

  1. Mermaid measures text with browser APIs, so its CLI renders through headless Chrome via Puppeteer.
  2. Pele's render(text) returns { svg }: MIT, zero runtime dependencies, no browser needed to render.
  3. It follows Mermaid 12.1.0 syntax, not Mermaid's layout, so output won't match pixel for pixel.
  4. Theme it with --pele-* CSS variables; colour changes need no re-render.
  5. The size and speed numbers are the site's own, with no published method.

Sources: Pele homepage · obsidianmd/pele README · npm registry, pele · Pele compatibility · mermaid-cli package.json · Mermaid Node.js API discussion · HN thread · Mermaid usage docs