remark plugin · build-time
remark-mermaid-tldraw
Pre-render your ```mermaid diagrams as
tldraw's warm, hand-drawn SVGs — at build
time. Light and dark variants, content-hash caching, zero client JS. The reader just gets an
<img>.
npm i -D remark-mermaid-tldraw tldraw @tldraw/mermaid playwright react react-dom
↑ a real mermaid flowchart, rendered by this package.
Same diagram, different hand
Mermaid's output is fine — it just always looks like a tool drew it. The same graph definition, run through a real tldraw editor, comes out sketched. And because it happens during your build, there's no mermaid runtime, no tldraw bundle, no layout pass in the browser.
```mermaid
flowchart TD
Start([request]) --> Q{cached?}
Q -->|yes| Serve[serve SVG]
Q -->|no| Render[render in tldraw]
Render --> Write[write light + dark]
Write --> Serve
```
Flowcharts, sequence diagrams, and more
tldraw models flowcharts and sequence diagrams natively. Types it can't draw (pie, gantt, class, ER) fall back to mermaid's own SVG, so you always get a real diagram.
Four pieces, then forget about it
-
Add the remark plugin
import remarkMermaidTldraw from "remark-mermaid-tldraw"; // in your MDX / markdown config remarkPlugins: [remarkMermaidTldraw]; -
Render the SVGs before you build
remark-mermaid-tldraw --content "src/**/*.{md,mdx}" --out public/diagramsOr use the Astro integration, which auto-renders and hot-reloads in dev:
import { mermaidTldraw } from "remark-mermaid-tldraw/astro"; export default defineConfig({ integrations: [mermaidTldraw()], markdown: { remarkPlugins: [remarkMermaidTldraw] }, }); -
Pick a variant in CSS
.mermaid-dark { display: none; } @media (prefers-color-scheme: dark) { .mermaid-light { display: none; } .mermaid-dark { display: inline; } } -
Write a fence
```mermaid width=380 flowchart TD A --> B ```
How it stays fast and stable
- Content-hash filenames. Each SVG is named after a hash of its mermaid source, so the URL never changes when the rendering code does. The plugin and the renderer agree on the filename with no shared manifest.
- Render-version markers. A marker comment inside each SVG tracks the render version — bump it and diagrams re-render in place, keeping their stable URLs.
- Browser only when needed. The headless Chromium launches only if something is actually stale. A clean build with cached diagrams never opens a browser.