Render Mermaid Diagrams to SVG or ASCII Art – beautiful-mermaid

Category: Chart & Graph , Javascript , Recommended | February 26, 2026
Authorlukilabs
Last UpdateFebruary 26, 2026
LicenseMIT
Tags
Views103 views
Render Mermaid Diagrams to SVG or ASCII Art – beautiful-mermaid

beautiful-mermaid is a JavaScript library that converts Mermaid diagrams into production-ready SVGs or terminal-friendly ASCII/Unicode art.

It supports 15 built-in themes and runs anywhere JavaScript executes, browsers, Node.js, Bun, Deno, or terminal, with zero DOM dependencies.

Features:

  • Dual Output Modes: Renders to SVG for rich UIs or ASCII/Unicode for terminals and plain text environments.
  • Built-in Themes: 15+ themes including Tokyo Night, Catppuccin, Nord, Dracula, and GitHub Dark/Light.
  • Live Theme Switching: Uses CSS custom properties on the SVG element for instant theme changes.
  • Shiki Compatibility: Extracts diagram colors from any VS Code theme in Shiki’s registry for consistent editor integration.
  • Mono Mode: Generates coherent diagrams from just two colors (background and foreground) using automated color derivation.
  • Five Diagram Types: Supports flowcharts, state diagrams, sequence diagrams, class diagrams, and ER diagrams.
  • Ultra-Fast Performance: Renders over 100 diagrams in under 500ms.

Use Cases:

  • AI Coding Assistants: Display data flows, state machines, and architecture diagrams directly in chat interfaces where users need instant visual context.
  • CLI Developer Tools: Render diagrams as ASCII art in terminal output for command-line applications, log viewers, and debugging tools.
  • Documentation Generators: Produce themed SVG diagrams that match your documentation site’s color scheme.
  • Terminal-Based IDEs: Show project structure, call graphs, and dependency trees as Unicode diagrams in Vim, Emacs, or other text-based editors.

How To Use It:

1. Install the beautiful-mermaid package and import it into your project:

# NPM
$ npm install beautiful-mermaid
# PNPM
$ pnpm install beautiful-mermaid
# BUN
$ bun add beautiful-mermaid
import { renderMermaid, THEMES, renderMermaidAscii } from 'beautiful-mermaid'

2. For browser environments without a bundler, load the beautiful-mermaid.browser.global.js script file from the dist folder or from a CDN:

The browser bundle exposes renderMermaid, renderMermaidAscii, THEMES, DEFAULTS, and fromShikiTheme on the global beautifulMermaid object.

<script src="https://unpkg.com/beautiful-mermaid/dist/beautiful-mermaid.browser.global.js"></script>
const { renderMermaid, THEMES } = beautifulMermaid;

3. Render a Mermaid diagram to SVG with default styling.

// Define a simple flowchart
const diagram = `
  graph TD
    A[Start] --> B{Decision}
    B -->|Yes| C[Action]
    B -->|No| D[End]
`
// Render to SVG string
const svg = await renderMermaid(diagram)
// The svg variable now contains a complete SVG string
// you can inject into the DOM or save to a file
document.getElementById('container').innerHTML = svg

4. For terminal environments, use renderMermaidAscii:

// Render using Unicode box-drawing characters (default)
const unicode = renderMermaidAscii(`graph LR; A --> B --> C`)
console.log(unicode)
// Output:
// ┌───┐     ┌───┐     ┌───┐
// │   │     │   │     │   │
// │ A │────►│ B │────►│ C │
// │   │     │   │     │   │
// └───┘     └───┘     └───┘
// Render using pure ASCII for maximum compatibility
const ascii = renderMermaidAscii(`graph LR; A --> B`, { useAscii: true })
console.log(ascii)
// Output:
// +---+     +---+
// |   |     |   |
// | A |---->| B |
// |   |     |   |
// +---+     +---+

5. Apply the following themes to the diagrams: zinc-light, zinc-dark, tokyo-night, tokyo-night-storm, tokyo-night-light, catppuccin-mocha, catppuccin-latte, nord, nord-light, dracula, github-light, github-dark, solarized-light, solarized-dark, one-dark.

// Render with Tokyo Night theme
const svg = await renderMermaid(diagram, THEMES['tokyo-night'])

6. Creating your own themes. The theming system requires only two colors at minimum.

// Mono mode: just background and foreground
const customTheme = {
  bg: '#0f0f0f',  // Dark background
  fg: '#e0e0e0',  // Light foreground
}
const svg = await renderMermaid(diagram, customTheme)

7. The library automatically derives all other colors (borders, fills, labels) using color-mix(). For richer themes, add optional enrichment colors:

const richTheme = {
  bg: '#0f0f0f',
  fg: '#e0e0e0',
  accent: '#ff6b6b',  // Arrow heads and highlights
  line: '#888888',    // Edge connectors
  muted: '#666666',   // Secondary text
  surface: '#1a1a1a', // Node fill tint
  border: '#333333',  // Node stroke
}
const svg = await renderMermaid(diagram, richTheme)

8. All theme colors are CSS custom properties on the SVG element. Change themes without re-rendering:

const svg = await renderMermaid(diagram, THEMES['github-light'])
// Insert SVG into DOM
const container = document.getElementById('diagram')
container.innerHTML = svg
// Switch to dark theme instantly
const svgElement = container.querySelector('svg')
svgElement.style.setProperty('--bg', '#0d1117')
svgElement.style.setProperty('--fg', '#c9d1d9')
svgElement.style.setProperty('--accent', '#4493f8')
// The diagram updates immediately without re-parsing Mermaid

9. Use any VS Code theme from Shiki’s registry:

import { getSingletonHighlighter } from 'shiki'
import { renderMermaid, fromShikiTheme } from 'beautiful-mermaid'
// Load a Shiki theme (e.g., Vitesse Dark)
const highlighter = await getSingletonHighlighter({
  themes: ['vitesse-dark', 'rose-pine']
})
// Extract diagram colors from the theme
const colors = fromShikiTheme(highlighter.getTheme('vitesse-dark'))
// Render with matching colors
const svg = await renderMermaid(diagram, colors)

10. All available options:

renderMermaid

  • bg (string): Background color. Defaults to #FFFFFF. Accepts any valid CSS color value.
  • fg (string): Foreground color for text and primary elements. Defaults to #27272A. Accepts any valid CSS color value.
  • line (string, optional): Color for edge connectors and lines. If omitted, derived from fg at 30% opacity mixed into bg.
  • accent (string, optional): Color for arrow heads and highlighted elements. If omitted, derived from fg at 50% opacity mixed into bg.
  • muted (string, optional): Color for secondary text and labels. If omitted, derived from fg at 60% opacity mixed into bg.
  • surface (string, optional): Background tint for node fills. If omitted, derived from fg at 3% opacity mixed into bg.
  • border (string, optional): Color for node strokes and borders. If omitted, derived from fg at 20% opacity mixed into bg.
  • font (string): Font family for all text. Defaults to Inter. Provide any CSS font-family string.
  • transparent (boolean): Render SVG with transparent background instead of the bg color. Defaults to false.
  • padding (number): Canvas padding in px. Defaults to 40.
  • nodeSpacing (number): Horizontal spacing between sibling nodes. Defaults to 24.
  • layerSpacing (number): Vertical spacing between layers. Defaults to 40.
  • componentSpacing (number): Spacing between disconnected components. Defaults to 24.
  • thoroughness (number): Crossing minimization trials (1-7, higher = better but slower). Defaults to 3.

renderMermaidAscii

  • useAscii (boolean): When true, uses ASCII characters (+, -, |). When false (default), uses Unicode box-drawing characters (, , ).
  • paddingX (number): Horizontal spacing between nodes. Defaults to 5.
  • paddingY (number): Vertical spacing between nodes. Defaults to 5.
  • boxBorderPadding (number): Padding inside node boxes. Defaults to 1.
  • colorMode: ‘none’, ‘auto’, ‘ansi16’, ‘ansi256’, ‘truecolor’, or ‘html’.
  • theme: Override default colors for ASCII output

Alternatives

  • Mermaid.js: The original Mermaid renderer. Provides more diagram types and mature ecosystem. Requires DOM and has heavier dependencies.
  • Kroki: Server-side diagram rendering API supporting multiple syntax formats including Mermaid.

FAQs:

Q: Can I use beautiful-mermaid in a Next.js server component?
A: Yes. Call renderMermaid in server components and pass the SVG string to the client. Make sure to mark the component as async since renderMermaid returns a Promise.

Q: How do I render diagrams with a transparent background for overlaying on images?
A: Set the transparent option to true when calling renderMermaid.

Q: Why do my ASCII diagrams look broken in some terminals?
A: Unicode box-drawing characters require Unicode support. If your terminal doesn’t render them correctly, pass { useAscii: true } to renderMermaidAscii. This uses basic ASCII characters that work everywhere. This uses basic ASCII characters that work everywhere.

Q: Can I dynamically change colors on an already-rendered SVG?
A: Yes. All colors are CSS custom properties on the SVG element. Use svgElement.style.setProperty('--bg', '#new-color') to update themes without re-rendering. This works for any of the color properties: --bg, --fg, --line, --accent, --muted, --surface, --border.

Q: What happens if I provide a color for accent but not for line?
A: The library uses your custom accent color for arrow heads and highlights. For line, it falls back to the derived value (30% of fg mixed into bg). You can mix and match custom colors with auto-derived ones based on what you want to control.

Changelog:

v1.1.2 (02/26/2026)

  • Full support for Mermaid’s xychart-beta syntax — bar charts, line charts, and combinations

v1.0.1/2 (02/24/2026)

  • Centering: contentAlignment H_CENTER V_CENTER for subgraphs
  • Node placement: BALANCED fixed alignment at root and subgraph level
  • Edge spacing: optimized edgeEdge, edgeEdgeBetweenLayers, edgeNodeBetweenLayers
  • High-degree nodes: special treatment for nodes with 8+ connections
  • Post-compaction: LEFT_RIGHT_CONSTRAINT_LOCKING at root level
  • Model order: NODES_AND_EDGES preservation at root level
  • Post-processing step that snaps same-layer nodes to uniform flow-axis positions, fixing the visual stagger caused by ELK’s orthogonal edge routing. Uses single-linkage clustering for accurate grouping across any fan-out size.
  • Fan-out/fan-in edges now share common trunk segments with subgraph-aware junction placement.
  • Bugfixes

v1.0.0 (02/23/2026)

  • ELK.js replaces dagre — fully synchronous layout via FakeWorker bypass, better edge routing and subgraph handling
  • Shape-aware edge clipping — edges terminate at actual shape boundaries (e.g. diamond vertices), not bounding boxes
  • New layout options — nodeSpacing, layerSpacing, componentSpacing, thoroughness for fine-grained control
  • Disconnected component support — graphs with unconnected subgraphs now lay out properly
  • Per-subgraph direction overrides — nested subgraphs can have independent LR/TD/BT/RL direction
  • <br> tags in node labels, edge labels, and subgraph headers — line breaks work everywhere
  • Inline formatting — <b>, <i>, <u>, <s> tags render as bold/italic/underline/strikethrough in SVG
  • Variable-width text measurement — character-class buckets (narrow, wide, CJK, emoji) instead of fixed-ratio estimation
  • ANSI color modes — none, ansi16, ansi256, truecolor, and html (for browser rendering)
  • AsciiTheme type — customize colors per role: fg, border, line, arrow, corner, junction
  • colorMode: ‘auto’ — auto-detects terminal capabilities
  • 12+ distinct node shapes in terminal output: rectangle, rounded, diamond, circle, hexagon, stadium, cylinder, doublecircle, subroutine, asymmetric, trapezoid, state-start, state-end
  • Edge bundling — fan-in/fan-out patterns merge into visual junctions (TD direction)
  • Multi-line labels in both nodes and edges
  • Multi-section boxes for class diagrams (name / attributes / methods) and ER diagrams
  • Canvas role tracking — each character tagged with semantic role for accurate colorization
  • Diagonal line validation — assertNoDiagonals() for test assertions
  • Semantic data attributes on all elements (data-id, data-from, data-to, data-style, data-label)
  • Improved arrow markers — combined fill + stroke for crisp rendering at small sizes
  • Better edge label pills — increased stroke width, improved contrast
  • dagre removed — replaced by ELK.js (API unchanged, layout results differ)
  • tsup.config.ts removed (no longer bundled separately)

You Might Be Interested In:


Leave a Reply