rehype-mermaid
A rehype plugin that renders Mermaid diagrams into inline SVG, PNG, or client-side markup inside a unified/remark/rehype pipeline.
Repository Health
Technical Analysis
rehype-mermaid is a rehype plugin that finds <pre class="mermaid"> and <code class="language-mermaid"> elements in a HAST tree and replaces them with a rendered version of the diagram. It slots directly into the unified/remark/rehype ecosystem, so it works out of the box with remark-rehype output, react-markdown, and MDX compilation pipelines without any extra glue code.
It supports four rendering strategies: inline SVG (the default, embedding the diagram markup directly in the document), an <img> tag with a base64 PNG or SVG data URI, or a pre-mermaid passthrough strategy that leaves the raw diagram for Mermaid to render client-side. Outside the browser it uses Playwright (via the companion mermaid-isomorphic package) as an optional peer dependency to headlessly render diagrams during a build step, so consumers only pay the Playwright cost when they actually need server/build-time rendering.
Options cover responsive dark-mode output via a <picture> element, a custom errorFallback handler for diagrams that fail to parse, and a colorScheme override that otherwise falls back to detecting a document’s <meta name="color-scheme"> tag. The plugin batches all diagrams in a file into a single render call, which keeps large documents with many diagrams from paying a per-diagram browser round trip.
What You Get
- A single default-exported unified/rehype plugin (
rehypeMermaid) that drops into an existingunified().use()chain with no other wiring - Four rendering strategies (
inline-svg,img-png,img-svg,pre-mermaid) covering static builds, email/RSS-safe images, and client-rendered diagrams - Optional responsive dark-mode output via a
<picture>element with a light/dark source pair - A pluggable
errorFallbackhook so a broken diagram can render a fallback node instead of failing the whole build - Automatic color-scheme detection from a document’s
<meta name="color-scheme">tag when no explicitcolorSchemeoption is given - Batched rendering of all diagrams in a file through a single Playwright-backed render pass via the companion
mermaid-isomorphicpackage
Common Use Cases
- Rendering Mermaid diagrams to static SVG at build time for a documentation site built with MDX or a markdown static site generator
- Adding Mermaid support to a
react-markdownpowered page viaMarkdownAsync/MarkdownHooks, without shipping the full Mermaid client bundle - Generating PNG diagram images for contexts that can’t execute JavaScript or inline SVG, such as emails or RSS feeds
- Using the
pre-mermaidstrategy to defer diagram rendering to the browser via the client-sidemermaidpackage when a site already loads it
Under The Hood
Architecture
The entire plugin lives in one file, src/rehype-mermaid.ts. rehypeMermaid(options) validates the strategy option, constructs a renderer via mermaid-isomorphic’s createMermaidRenderer, and returns a unified transformer (ast, file). That transformer walks the HAST tree with unist-util-visit-parents, using isMermaidElement to match <pre class="mermaid"> and <code class="language-mermaid"> nodes (carefully skipping <code> elements that have non-whitespace sibling content inside their wrapping <pre>), and collects each match as a CodeInstance holding its diagram text and inclusive ancestor chain. For the synchronous pre-mermaid strategy, matched nodes are swapped in place immediately; for the other three strategies, all collected diagrams are rendered together in one batched call (plus a second batched call for dark-mode variants when dark is set), and Promise.all resolves both passes before nodes are replaced with either an inline SVG fragment (fromHtmlIsomorphic) or an <img>/<picture> element (toImageElement). Error handling is centralized in handleError, which defers to a caller-supplied errorFallback or throws a fatal VFileMessage with a stable ruleId. The clean separation between tree-matching, batched rendering, and result-to-HAST serialization means a change to the underlying Mermaid renderer would only touch the middle layer.
Tech Stack
Written in strict-mode TypeScript targeting ES2022 with Node16 module resolution and verbatimModuleSyntax, built as an ESM-only composite TypeScript project via tsc --build. It sits squarely in the unified/hast ecosystem: unified for the plugin contract, hast-util-from-html-isomorphic and hast-util-to-text for HAST parsing/serialization, unist-util-visit-parents for tree traversal, and vfile/vfile-message for diagnostics. Actual diagram rendering is delegated to the same author’s mermaid-isomorphic package, which can render in a real browser or headlessly through an optional playwright peer dependency — so consumers who only need client-side rendering never have to install Playwright. mini-svg-data-uri and space-separated-tokens handle small serialization/parsing chores.
Code Quality
Testing uses Node’s built-in node:test runner together with snapshot-fixtures, which drives 14 fixture directories (covering plain code blocks, pre/code element combinations, sibling text and element edge cases, and all four color-scheme detection permutations) through each rendering strategy and diffs the Prettier-formatted output against committed snapshots; PNG-strategy fixtures are explicitly marked ignore since PNG output isn’t pixel-perfect across platforms, while SVG and pre-mermaid fixtures are asserted exactly. c8 measures coverage. CI runs ESLint, Prettier, and remark --frail lint passes plus the test suite across a Node 18/20/22/24 matrix. No untyped code paths and no swallowed errors were found — failures either hit the caller’s errorFallback or become fatal VFileMessages.
API Design
The public surface is a single default export plus one options interface, matching the exact unified().use(plugin, options) convention every rehype/remark plugin author already knows — there is no bespoke setup step. Every option (strategy, dark, colorScheme, errorFallback, prefix, mermaidConfig, launchOptions) is documented with TSDoc directly above its declaration, and the README walks through remark, React, and MDX integration with copy-pasteable examples for each. The only friction point is implicit: consumers doing non-browser rendering must separately install and configure Playwright, a detail covered in the README’s installation section rather than surfaced by the API itself.
Used by 2 apps in this directory
authentik
Authentication · Security
The self-hosted Identity Provider that replaces Okta, Auth0, and Entra ID with a unified SSO platform supporting SAML, OAuth2/OIDC, LDAP, RADIUS, and WebAuthn.
Terrateam
Devops · Developer Tools
GitOps automation for Terraform, Pulumi, and IaC at scale