Markdown + Mermaid made simple - A powerful markdown renderer with first-class Mermaid diagram support
npm install mdmaidMarkdown + Mermaid rendering library
A preconfigured markdown renderer with Mermaid diagram support. Built for personal use across mdmaid.nvim and oles.md blog.
- Markdown → HTML via remark (GFM, slug, autolink-headings) `` const html = await renderMarkdown( \ Render mermaid diagrams to SVG on the server (requires puppeteer): ` // Use the bundled Departure Mono font await closeBrowser(); Or with custom fonts: ` More efficient for multiple diagrams: ` const svgs = await renderMermaidBatch( await closeBrowser(); Option 1: CSS Invert (simple, used in oles.md) Render once in light theme, use CSS to invert in dark mode: ` Option 2: Dual Theme Rendering Render separate versions for light and dark: ` const results = await renderMermaidWithThemes( // results[0] = { theme: 'default', svg: '' } await closeBrowser(); ` #### #### #### Render single diagram to SVG. #### Render multiple diagrams efficiently (reuses browser). #### Render diagram with multiple themes for light/dark mode. #### Batch render with multiple themes. #### Clean up puppeteer browser when done. #### Bundled Departure Mono font config. Use for consistent rendering: #### Options interface FontConfig { - Live reload on file changes --- The pain: Potential approach: The pain: Potential approach: The pain: SVG diagrams are invisible to screen readers. Potential approach: Current SSR requires puppeteer. Exploring: --- This library exists because I needed shared rendering logic between my Neovim plugin and my blog. The SSR module is extracted from oles.md and works. The "ideas" above are things that would be nice to have but aren't priorities. MIT
- Mermaid code blocks → (client-side rendering)
- SSR module - Server-side mermaid → SVG rendering with font embedding
- Bundled font - Departure Mono included for consistent diagram rendering
- CLI for quick rendering and dev server with live reload
- Dev server extras: ToC sidebar, image zoom, print stylesInstallation
bash
npm install mdmaidFor SSR (optional)
npm install puppeteer
``Usage
$3
typescript
import { renderMarkdown } from 'mdmaid';Hello
\\mermaid\
graph TD
A[Start] --> B[End]
\\);`
// Returns HTML with ...
// Mermaid renders client-side$3
typescript
import { renderMermaidToSVG, closeBrowser, DEFAULT_FONT } from 'mdmaid/ssr';
const svg = await renderMermaidToSVG('graph TD; A-->B;', {
fonts: [DEFAULT_FONT],
embedFonts: true,
});
`typescript`
const svg = await renderMermaidToSVG('graph TD; A-->B;', {
fonts: [
// Local font file
{ family: 'My Font', path: './fonts/MyFont.woff2' },
// Or external URL
{ family: 'Fira Code', url: 'https://example.com/FiraCode.woff2' },
],
mermaid: { theme: 'default' },
embedFonts: true,
});$3
typescript
import { renderMermaidBatch, closeBrowser } from 'mdmaid/ssr';
['graph TD; A-->B;', 'sequenceDiagram; A->>B: Hi'],
{ embedFonts: true }
);
`$3
css`
.dark .mermaid img { filter: invert(1); }
/ or with Tailwind: className="dark:invert" /typescript
import { renderMermaidWithThemes, closeBrowser } from 'mdmaid/ssr';
'graph TD; A-->B;',
['default', 'dark'], // themes to render
{ embedFonts: true }
);
// results[1] = { theme: 'dark', svg: '' }
`$3
bashRender markdown to stdout
mdmaid README.mdRender to file
mdmaid README.md -o output.htmlDev server with live reload
mdmaid serve docs/index.md --watch --port 3333Batch render mermaid diagrams to SVG (requires puppeteer)
mdmaid render-diagrams _posts/ --out public/diagrams/ --manifest
`renderMarkdown(markdown, options?)API Reference
$3
`typescript`
const html = await renderMarkdown(content, {
sanitize: false, // HTML sanitization (default: false)
});extractMermaidBlocks(markdown)`typescript`
const blocks = extractMermaidBlocks(content);
// ['graph TD\n A --> B', 'sequenceDiagram\n ...']renderMermaidToSVG(code, options?)$3
renderMermaidBatch(codes, options?)renderMermaidWithThemes(code, themes?, options?)renderMermaidBatchWithThemes(codes, themes?, options?)closeBrowser()DEFAULT_FONT`typescript`
import { DEFAULT_FONT } from 'mdmaid/ssr';
// { family: 'Departure Mono', path: '...', weight: 400, style: 'normal' }`typescript`
interface MermaidSSROptions {
fonts?: FontConfig[]; // Fonts to use
mermaid?: MermaidConfig; // Mermaid configuration
puppeteer?: PuppeteerConfig; // Puppeteer launch options
embedFonts?: boolean; // Embed fonts in SVG (default: false)
}
family: string; // Font family name
path?: string; // Local file path (.woff2, .woff, .ttf)
url?: string; // External URL (CDN, direct font file)
weight?: number; // Font weight (default: 400)
style?: string; // Font style (default: 'normal')
}ZDev Server Features
- Auto-generated Table of Contents sidebar
- Image magnifier (hold or click to zoom)
- Print-friendly stylesIdeas Still Being Explored
$3
- Diagrams clip on mobile / narrow containers
- No text wrapping in nodes (manual hell)accTitle
- Large diagrams become unreadable thumbnails
- Smart container-aware rendering
- Pan/zoom for large diagrams
- Viewport-based sizing hints$3
- Works in VS Code, breaks on GitHub (version mismatch)
- Single typo → ugly error block on published site
- No graceful fallback
- Pre-flight syntax validation
- Graceful error states
- Version compatibility checking$3
and accDescr exist but nobody knows about them.`
- Auto-generate descriptions from diagram structure
- Enforce/encourage accessibility metadata
- Semantic alternatives for simple diagrams$3
- jsdom-based rendering
- WASM-based mermaidThe Honest Truth
Development
bash``
npm install
npm run build
npm run dev # watch modeTest locally
node bin/mdmaid.js test.md -o test-output.html
node bin/mdmaid.js serve test.md --watchLicense