Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

Mermaid Administrator & Developer Guide

Generated May 2026 from mermaid-js/mermaid at 8b52e53

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

1. Architecture Overview

Mermaid is a JavaScript-based diagramming and charting library that renders Markdown-inspired text definitions into SVG diagrams in the browser. It is distributed as an npm package (mermaid v11.14.0), operates entirely client-side, and exposes no server-side components, CLI commands, or API endpoints.

1.1 Monorepo Structure

The codebase is organized as a pnpm monorepo (root name mermaid-monorepo v10.2.4) containing eight packages:

Package npm Name Version Purpose
packages/mermaid mermaid 11.14.0 Core library: parsing, rendering, config, themes
packages/parser @mermaid-js/parser 1.1.0 Langium-based grammar parser for newer diagram types
packages/mermaid-layout-elk @mermaid-js/layout-elk 0.2.1 ELK layout engine integration (elkjs)
packages/mermaid-layout-tidy-tree @mermaid-js/layout-tidy-tree 0.2.1 Bidirectional tidy-tree layout for mindmaps
packages/mermaid-zenuml @mermaid-js/mermaid-zenuml 0.2.2 ZenUML sequence diagram integration
packages/mermaid-example-diagram @mermaid-js/mermaid-example-diagram 9.3.0 Reference implementation for external diagram plugins
packages/examples @mermaid-js/examples 1.2.0 Diagram definition samples for all 27 types
packages/tiny @mermaid-js/tiny 11.14.0 Minimal/tree-shaken build variant

1.2 Core Rendering Pipeline

Every diagram flows through the same pipeline:

Text Input
  → detectType()           # regex-based diagram type detection
  → getDiagramLoader()     # lazy-load diagram module if not registered
  → Parser                 # jison (legacy) or langium (modern)
  → Diagram DB             # in-memory data store populated by parser
  → Renderer               # SVG generation using d3 + layout algorithm
  → SVG Output             # sanitized via DOMPurify

The pipeline is orchestrated by Diagram.fromText() (static factory in packages/mermaid/src/Diagram.ts), which detects the diagram type, loads the appropriate parser/db/renderer triplet, runs the parser, and returns a Diagram instance ready for rendering.

1.3 Key Source Modules

Module Path Responsibility
mermaid.ts packages/mermaid/src/mermaid.ts Public API: initialize, run, parse, render, registerExternalDiagrams
mermaidAPI.ts packages/mermaid/src/mermaidAPI.ts Internal API: createCssStyles, putIntoIFrame, render, parse
Diagram.ts packages/mermaid/src/Diagram.ts Diagram class with fromText static factory
config.ts packages/mermaid/src/config.ts Three-tier config management: default, site, current
config.type.ts packages/mermaid/src/config.type.ts TypeScript interfaces for all configuration (auto-generated from JSON Schema)
defaultConfig.ts packages/mermaid/src/defaultConfig.ts Default values loaded from config.schema.yaml
detectType.ts packages/mermaid/src/diagram-api/detectType.ts Regex-based diagram type detection and lazy-loader registry
diagramAPI.ts packages/mermaid/src/diagram-api/diagramAPI.ts Diagram registration and retrieval
diagram-orchestration.ts packages/mermaid/src/diagram-api/diagram-orchestration.ts Registers all built-in diagram types
logger.ts packages/mermaid/src/logger.ts Configurable log levels (trace through fatal)
utils.ts packages/mermaid/src/utils.ts Entity encoding, init detection, ID generation
internals.ts packages/mermaid/src/internals.ts Deprecated internal helpers for external diagram plugins
errors.ts packages/mermaid/src/errors.ts UnknownDiagramError class

1.4 Diagram Type Architecture

Each of the 27 built-in diagram types follows a consistent module pattern within packages/mermaid/src/diagrams/{type}/:

File Role
*Detector.ts Regex function to detect this diagram type from raw text
*Diagram.ts Diagram definition export: { db, parser, renderer, styles }
*Db.ts Data store: parse results, getters/setters, clear()
*Renderer.ts SVG rendering logic using d3
Parser (.jison or .langium) Grammar definition
styles.ts/styles.js CSS generation functions for theming

Note

Older diagram types (flowchart, sequence, gantt, class, state, ER, pie, C4, requirement, user-journey, git graph) use jison parsers (.jison grammar files compiled to JavaScript). Newer types (packet, info, pie v2, gitGraph v2, radar, architecture, wardley, treemap, treeView, eventmodeling, venn) use Langium grammars (.langium files) via the @mermaid-js/parser package.

1.5 Supported Diagram Types (27)

flowchart, sequence, class, state, er, gantt, pie, mindmap, timeline, quadrant-chart, xychart, requirement, c4, sankey, packet, block, git graph, user-journey, architecture, ishikawa, kanban, radar, venn, treemap, tree-view, eventmodeling, wardley


2. System Requirements

2.1 Development Environment

Requirement Version
Node.js Version specified in .node-version file at repo root
pnpm 10.30.3 (enforced via packageManager field with integrity hash)
TypeScript ~5.8.0
OS Any platform supporting Node.js (Linux, macOS, Windows)

2.2 Runtime Dependencies (Core Package)

Dependency Version Purpose
d3 ^7.9.0 SVG rendering and DOM manipulation
dagre-d3-es 7.0.14 Default graph layout (dagre algorithm)
dompurify ^3.3.1 HTML/SVG sanitization (XSS prevention)
cytoscape ^3.33.1 Alternative layout engine
cytoscape-cose-bilkent ^4.1.0 CoSE-Bilkent layout for cytoscape
cytoscape-fcose ^2.2.0 fCoSE layout for cytoscape
katex ^0.16.25 LaTeX math rendering
marked ^16.3.0 Markdown parsing within diagrams
roughjs ^4.6.6 Hand-drawn style rendering
dayjs ^1.11.19 Date handling (gantt diagrams)
@braintree/sanitize-url latest URL sanitization
khroma latest Color manipulation for themes
stylis latest CSS processing
uuid latest ID generation
ts-dedent latest Template literal dedenting

2.3 Runtime Dependencies (Satellite Packages)

Package Key Dependency Version
@mermaid-js/parser langium ^4.0.0
@mermaid-js/layout-elk elkjs ^0.9.3

2.4 Browser Requirements

Mermaid targets modern browsers with ES module support. The esbuild configuration targets the modules build output. No polyfills are included; consumers must provide them if targeting older browsers.

Important

Mermaid is a browser-side library only. It requires a DOM environment. Server-side rendering requires a DOM shim (e.g., jsdom) or a headless browser. The library auto-registers a window.addEventListener('load', ...) listener when document is defined.


3. Configuration Reference

Mermaid uses a three-tier configuration architecture:

  1. defaultConfig -- Immutable baseline loaded from config.schema.yaml via a custom Vite plugin, frozen with Object.freeze().
  2. siteConfig -- Set via mermaid.initialize(config). Merges onto defaultConfig. Persists across reset() calls. This is where site-wide defaults belong.
  3. currentConfig -- Active config during rendering. Starts as a copy of siteConfig, then has directives applied on top. Reset between diagrams via reset().
defaultConfig (frozen)
    └──► siteConfig (via initialize)
            └──► currentConfig (via directives)

3.1 Config API Functions

Function Description
setSiteConfig(conf) Sets siteConfig by merging conf onto defaultConfig. Recalculates theme variables.
getSiteConfig() Returns a deep copy of siteConfig.
setConfig(conf) Merges conf into currentConfig (sanitized against secure keys).
getConfig() Returns a deep copy of currentConfig.
reset(config?) Resets currentConfig to siteConfig (or provided config). Clears all directives.
addDirective(directive) Pushes a directive, sanitizes it, and recalculates currentConfig.
updateCurrentConfig(siteCfg, directives) Recalculates currentConfig from site config + accumulated directives.
saveConfigFromInitialize(conf) Stores the config passed to initialize() for later reference.
getUserDefinedConfig() Returns merged user config (initialize config + all directives).
getEffectiveHtmlLabels(config) Resolves the effective htmlLabels value considering deprecated flowchart.htmlLabels.
evaluate(val) Converts string/boolean to boolean (treats 'false', 'null', '0' as false).

Warning

The secure array in config prevents certain keys from being overridden via directives. By default, securityLevel, maxTextSize, and other sensitive keys are in this array. Attempting to set a secure key via a %%{init: {...}}%% directive will silently fail with a debug log message.

3.2 Global Configuration (MermaidConfig)

Key Type Default Description
theme 'default' | 'base' | 'dark' | 'forest' | 'neutral' | 'neo' | 'neo-dark' | 'redux' | 'redux-dark' | 'redux-color' | 'redux-dark-color' | 'null' 'default' CSS theme for diagram rendering
themeVariables any (computed) Theme variable overrides; processed by theme's getThemeVariables()
themeCSS string undefined Raw CSS to override theme styles
look 'classic' | 'handDrawn' | 'neo' 'classic' Visual style for diagram rendering
handDrawnSeed number 0 Seed for hand-drawn style (0 = random). Set non-zero for deterministic output.
layout string undefined Layout algorithm override ('dagre', 'elk', etc.)
maxTextSize number 50000 Maximum character length of input text
maxEdges number 500 Maximum number of edges in a graph
darkMode boolean false Enable dark mode theme adjustments
htmlLabels boolean true Use HTML for rendering labels (enables richer formatting)
fontFamily string '"trebuchet ms", verdana, arial, sans-serif' CSS font-family for diagrams
altFontFamily string undefined Alternative font family
fontSize number 16 Base font size in pixels
logLevel 'trace' | 0 | 'debug' | 1 | 'info' | 2 | 'warn' | 3 | 'error' | 4 | 'fatal' | 5 'fatal' Console log verbosity
securityLevel 'strict' | 'loose' | 'antiscript' | 'sandbox' 'strict' Security policy for rendering
startOnLoad boolean true Auto-render diagrams when page loads
arrowMarkerAbsolute boolean false Use absolute paths for arrow markers (needed with <base> tag)
secure string[] ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize', 'maxEdges'] Keys that cannot be overridden by directives
legacyMathML boolean false Fall back to KaTeX rendering when MathML unsupported
forceLegacyMathML boolean false Always use KaTeX (ignores legacyMathML)
deterministicIds boolean false Generate deterministic SVG element IDs (for source control stability)
deterministicIDSeed string undefined Seed string for deterministic IDs
dompurifyConfig DOMPurifyConfiguration undefined Custom DOMPurify options
wrap boolean undefined Enable text wrapping globally
markdownAutoWrap boolean true Auto-wrap markdown text
suppressErrorRendering boolean false Suppress "Syntax error" diagram insertion into DOM

3.3 ELK Layout Configuration (elk)

Key Type Default Description
elk.mergeEdges boolean false Allow edges to share paths
elk.nodePlacementStrategy 'SIMPLE' | 'NETWORK_SIMPLEX' | 'LINEAR_SEGMENTS' | 'BRANDES_KOEPF' 'BRANDES_KOEPF' Node placement algorithm
elk.cycleBreakingStrategy 'GREEDY' | 'DEPTH_FIRST' | 'INTERACTIVE' | 'MODEL_ORDER' | 'GREEDY_MODEL_ORDER' (default) Strategy for breaking graph cycles
elk.forceNodeModelOrder boolean false Preserve model-order node positions during crossing minimization
elk.considerModelOrder 'NONE' | 'NODES_AND_EDGES' | 'PREFER_EDGES' | 'PREFER_NODES' 'NODES_AND_EDGES' How to preserve model ordering

3.4 Flowchart Configuration (flowchart: FlowchartDiagramConfig)

Key Type Default Description
titleTopMargin number Margin above diagram title
subGraphTitleMargin {top?: number, bottom?: number} Margins around subgraph titles
arrowMarkerAbsolute boolean false Absolute arrow marker paths
diagramPadding number 8 Padding around entire diagram (px)
htmlLabels boolean | null true Deprecated. Use global htmlLabels instead.
nodeSpacing number 50 Spacing between nodes on same level
rankSpacing number 50 Spacing between nodes on different levels
curve 'basis' | 'bumpX' | 'bumpY' | 'cardinal' | 'catmullRom' | 'linear' | 'monotoneX' | 'monotoneY' | 'natural' | 'step' | 'stepAfter' | 'stepBefore' | 'rounded' 'basis' Edge curve interpolation
padding number Padding between labels and shapes
defaultRenderer 'dagre-d3' | 'dagre-wrapper' | 'elk' 'dagre-wrapper' Rendering engine
wrappingWidth number 200 Max text width before wrapping
inheritDir boolean false Subgraphs inherit parent graph direction
useMaxWidth boolean true Scale to container width

3.5 Sequence Diagram Configuration (sequence: SequenceDiagramConfig)

Key Type Default Description
arrowMarkerAbsolute boolean false Absolute arrow marker paths
hideUnusedParticipants boolean false Hide participants not involved in messages
activationWidth number 10 Width of activation rectangles
diagramMarginX number 50 Left/right margin
diagramMarginY number 10 Top/bottom margin
actorMargin number 50 Spacing between actors
width number 150 Actor box width
height number 65 Actor box height
boxMargin number 10 Margin around loop/alt/opt boxes
boxTextMargin number 5 Text margin inside boxes
noteMargin number 10 Margin around notes
messageMargin number 35 Space between messages
messageAlign 'left' | 'center' | 'right' 'center' Message text alignment
mirrorActors boolean true Mirror actors below diagram
forceMenus boolean false Always show actor popup menus
bottomMarginAdj number 1 Bottom edge extension
rightAngles boolean false Self-referencing arrows as right angles
showSequenceNumbers boolean false Display sequence numbers
actorFontSize string | number 14 Actor label font size
actorFontFamily string '"Open Sans", sans-serif' Actor label font
actorFontWeight string | number 400 Actor label font weight
noteFontSize string | number 14 Note font size
noteFontFamily string '"trebuchet ms", verdana, arial, sans-serif' Note font family
noteFontWeight string | number 400 Note font weight
noteAlign 'left' | 'center' | 'right' 'center' Note text alignment
messageFontSize string | number 16 Message font size
messageFontFamily string '"trebuchet ms", verdana, arial, sans-serif' Message font family
messageFontWeight string | number 400 Message font weight
wrap boolean false Enable auto-wrap
wrapPadding number 10 Padding for wrapped text
labelBoxWidth number 50 Loop/alt/opt label box width
labelBoxHeight number 20 Loop/alt/opt label box height

3.6 Gantt Diagram Configuration (gantt: GanttDiagramConfig)

Key Type Default Description
titleTopMargin number 25 Top margin for title
barHeight number 20 Height of task bars
barGap number 4 Gap between bars
topPadding number 50 Padding above chart
rightPadding number 75 Right padding for section labels
leftPadding number 75 Left padding for section labels
gridLineStartPadding number 35 Grid line vertical start
fontSize number 11 General font size
sectionFontSize string | number 11 Section label font size
numberSectionStyles number 4 Number of alternating section styles
axisFormat string '%Y-%m-%d' Date format for axis (d3 time format)
tickInterval string undefined Axis tick interval (e.g., '1day', '1week')
topAxis boolean false Show date labels on top
displayMode '' | 'compact' '' Compact mode collapses vertical space
weekday 'monday' | ... | 'sunday' 'sunday' Week start day

3.7 Class Diagram Configuration (class: ClassDiagramConfig)

Key Type Default Description
titleTopMargin number 25 Top margin for title
arrowMarkerAbsolute boolean false Absolute arrow markers
dividerMargin number 10 Margin around class dividers
padding number 5 Padding inside class boxes
textHeight number 10 Text line height
defaultRenderer 'dagre-d3' | 'dagre-wrapper' | 'elk' 'dagre-wrapper' Rendering engine
nodeSpacing number 50 Spacing between nodes
rankSpacing number 50 Spacing between ranks
diagramPadding number 8 Diagram padding
htmlLabels boolean true HTML label rendering
hideEmptyMembersBox boolean false Hide empty attribute/method sections

3.8 State Diagram Configuration (state: StateDiagramConfig)

Key Type Default Description
titleTopMargin number 25 Top margin for title
dividerMargin number 10 Divider margin
sizeUnit number 5 Base size unit
padding number 8 Padding
textHeight number 10 Text height
titleShift number -15 Title position shift
noteMargin number 10 Note margin
nodeSpacing number 50 Node spacing
rankSpacing number 50 Rank spacing
forkWidth number 70 Fork/join bar width
forkHeight number 7 Fork/join bar height
miniPadding number 2 Minimum padding
fontSizeFactor number 5.02 Font factor for edge label width estimation
fontSize number 24 Font size
labelHeight number 16 Label height
edgeLengthFactor string '20' Edge length factor
compositTitleSize number 35 Composite state title size
radius number 5 Corner radius
defaultRenderer 'dagre-d3' | 'dagre-wrapper' | 'elk' 'dagre-wrapper' Rendering engine

3.9 ER Diagram Configuration (er: ErDiagramConfig)

Key Type Default Description
titleTopMargin number 25 Top margin for title
diagramPadding number 20 Diagram padding
layoutDirection 'TB' | 'BT' | 'LR' | 'RL' 'TB' Layout direction
minEntityWidth number 100 Minimum entity box width
minEntityHeight number 75 Minimum entity box height
entityPadding number 15 Entity internal padding
nodeSpacing number 80 Node spacing
rankSpacing number 80 Rank spacing
stroke string 'gray' Stroke color
fill string 'honeydew' Fill color
fontSize number 12 Font size

3.10 Pie Diagram Configuration (pie: PieDiagramConfig)

Key Type Default Description
textPosition number 0.75 Label position (0=center, 1=edge)
useMaxWidth boolean true Scale to container

3.11 Quadrant Chart Configuration (quadrantChart: QuadrantChartConfig)

Key Type Default Description
chartWidth number 500 Chart width
chartHeight number 500 Chart height
titleFontSize number 20 Title font size
titlePadding number 10 Title padding
quadrantPadding number 5 Quadrant square padding
xAxisLabelPadding number 5 X-axis label padding
yAxisLabelPadding number 5 Y-axis label padding
xAxisLabelFontSize number 16 X-axis label font size
yAxisLabelFontSize number 16 Y-axis label font size
quadrantLabelFontSize number 16 Quadrant title font size
quadrantTextTopPadding number 5 Quadrant title top padding
pointTextPadding number 5 Point label padding
pointLabelFontSize number 12 Point label font size
pointRadius number 5 Point radius
xAxisPosition 'top' | 'bottom' 'top' X-axis label position
yAxisPosition 'left' | 'right' 'left' Y-axis label position
quadrantInternalBorderStrokeWidth number 1 Internal border width
quadrantExternalBorderStrokeWidth number 2 External border width

3.12 XY Chart Configuration (xyChart: XYChartConfig)

Key Type Default Description
width number 700 Chart width
height number 500 Chart height
titleFontSize number 20 Title font size
titlePadding number 10 Title padding
showDataLabel boolean false Show value labels on bars
showDataLabelOutsideBar boolean false Place labels outside bars
showTitle boolean true Display chart title
chartOrientation 'vertical' | 'horizontal' 'vertical' Plot orientation
plotReservedSpacePercent number 50 Minimum % space for plot area

XY Chart Axis (xAxis/yAxis: XYChartAxisConfig):

Key Type Default Description
showLabel boolean true Show axis tick labels
labelFontSize number 14 Tick label font size
labelPadding number 5 Tick label padding
showTitle boolean true Show axis title
titleFontSize number 16 Axis title font size
titlePadding number 5 Axis title padding
showTick boolean true Show tick marks
tickLength number 5 Tick mark length
tickWidth number 2 Tick mark width
showAxisLine boolean true Show axis line
axisLineWidth number 2 Axis line width

3.13 Journey Diagram Configuration (journey: JourneyDiagramConfig)

Key Type Default Description
diagramMarginX number 50 Horizontal margin
diagramMarginY number 10 Vertical margin
leftMargin number 150 Left margin for actor names
maxLabelWidth number 200 Maximum actor label width
width number 150 Actor box width
height number 50 Actor box height
boxMargin number 10 Box margin
boxTextMargin number 5 Box text margin
noteMargin number 10 Note margin
messageMargin number 35 Message spacing
messageAlign 'left' | 'center' | 'right' 'center' Message alignment
bottomMarginAdj number 1 Bottom edge adjustment
rightAngles boolean false Right-angle self-arrows
taskFontSize string | number 14 Task label font size
taskFontFamily string '"Open Sans", sans-serif' Task font
taskMargin number 50 Task margin
activationWidth number 10 Activation box width
textPlacement string 'fo' Text rendering method
actorColours string[] Actor color palette
sectionFills string[] Section fill colors
sectionColours string[] Section border colors
titleColor string '' Title text color
titleFontFamily string '' Title font family
titleFontSize string '' Title font size

3.14 Timeline Diagram Configuration (timeline: TimelineDiagramConfig)

Shares the same structure as JourneyDiagramConfig with these additions:

Key Type Default Description
padding number General padding
disableMulticolor boolean false Disable multicolor sections

3.15 Git Graph Configuration (gitGraph: GitGraphDiagramConfig)

Key Type Default Description
titleTopMargin number 25 Top margin for title
diagramPadding number 8 Diagram padding
nodeLabel {width, height, x, y} Node label dimensions
mainBranchName string 'main' Default main branch name
mainBranchOrder number 0 Main branch display order
showCommitLabel boolean true Show commit labels
showBranches boolean true Show branch lines
rotateCommitLabel boolean true Rotate commit labels
parallelCommits boolean false Display parallel commits
arrowMarkerAbsolute boolean false Absolute arrow paths

3.16 C4 Diagram Configuration (c4: C4DiagramConfig)

The C4 diagram configuration contains extensive font and color settings for every C4 element type (Person, System, Container, Component -- each with regular and external variants, plus DB and Queue subtypes). Key structural settings:

Key Type Default Description
diagramMarginX number 50 Horizontal margin
diagramMarginY number 10 Vertical margin
c4ShapeMargin number 50 Margin between shapes
c4ShapePadding number 20 Padding inside shapes
width number 216 Person box width
height number 60 Person box height
boxMargin number 10 Box margin
c4ShapeInRow number 4 Shapes per row
c4BoundaryInRow number 2 Boundaries per row
wrap boolean true Enable text wrapping
wrapPadding number 10 Wrap padding

Each element type has *FontSize, *FontFamily, *FontWeight, *_bg_color, *_border_color, and *Font (calculator function) settings. The naming pattern follows: {element}FontSize, external_{element}FontSize, etc.

3.17 Sankey Diagram Configuration (sankey: SankeyDiagramConfig)

Key Type Default Description
width number 600 Diagram width
height number 400 Diagram height
linkColor SankeyLinkColor | string 'gradient' Link coloring: 'source', 'target', 'gradient', or CSS color
nodeAlignment 'left' | 'right' | 'center' | 'justify' 'justify' Node alignment (d3-sankey)
showValues boolean true Show values alongside titles
prefix string '' Value prefix (e.g., '$')
suffix string '' Value suffix (e.g., 'k')
nodeWidth number 15 Node width
nodePadding number 10 Vertical padding between nodes
labelStyle 'legacy' | 'outlined' 'legacy' Label rendering style
nodeColors Record<string, string> {} Custom node color mapping

3.18 Packet Diagram Configuration (packet: PacketDiagramConfig)

Key Type Default Description
rowHeight number 32 Height per row
bitWidth number 20 Width per bit
bitsPerRow number 32 Bits displayed per row
showBits boolean true Show bit numbers
paddingX number 5 Horizontal padding
paddingY number 5 Vertical padding

3.19 Other Diagram Configurations

Diagram Config Key Key Settings
Architecture architecture padding, iconSize, fontSize, randomize (randomize initial node positions)
Mindmap mindmap padding, maxNodeWidth, layoutAlgorithm
Ishikawa ishikawa diagramPadding, useMaxWidth
Kanban kanban padding, sectionWidth, ticketBaseUrl
Block block padding
Event Modeling eventmodeling padding, rowHeight
Tree View treeView rowIndent, paddingX, paddingY, lineThickness
Radar radar width, height, marginTop/Right/Bottom/Left, axisScaleFactor, axisLabelFactor, curveTension
Venn venn width, height, padding, useDebugLayout
Wardley wardley-beta width, height, padding, nodeRadius, nodeLabelOffset, axisFontSize, labelFontSize, showGrid
Requirement requirement rect_fill, text_color, rect_border_size/color, rect_min_width/height, fontSize, rect_padding, line_height

3.20 Base Diagram Config (BaseDiagramConfig)

All per-diagram configs extend BaseDiagramConfig:

Key Type Default Description
useWidth number undefined Fixed width override
useMaxWidth boolean true Scale to container width (responsive)

4. Deployment & Scaling

4.1 Installation Methods

npm/pnpm/yarn:

npm install mermaid
# or
pnpm add mermaid
# or
yarn add mermaid

CDN (ESM):

<script type="module">
  import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
  mermaid.initialize({ startOnLoad: true });
</script>

4.2 Build Outputs

The esbuild pipeline (.esbuild/build.ts) produces multiple distribution formats in packages/mermaid/dist/:

File Format Use Case
mermaid.esm.min.mjs ES Module (minified) Modern bundlers, CDN
mermaid.esm.mjs ES Module Development
mermaid.min.js IIFE (minified) Script tag inclusion
mermaid.js IIFE Development
mermaid.d.ts TypeScript declarations IDE support

4.3 Integration Patterns

Auto-rendering (simplest):

<div class="mermaid">
  graph TD;
    A-->B;
</div>
<script type="module">
  import mermaid from '/path/to/mermaid.esm.min.mjs';
  mermaid.initialize({ startOnLoad: true });
</script>

Programmatic rendering:

import mermaid from 'mermaid';

mermaid.initialize({ startOnLoad: false, theme: 'dark' });

const { svg, bindFunctions } = await mermaid.render('diagram-id', 'graph TD; A-->B');
document.getElementById('output').innerHTML = svg;
if (bindFunctions) {
  bindFunctions(document.getElementById('output'));
}

Targeted node rendering:

await mermaid.run({
  nodes: [document.getElementById('my-diagram')],
  suppressErrors: true,
  postRenderCallback: (id) => console.log(`Rendered: ${id}`),
});

Tip

When calling mermaid.render() or mermaid.parse() concurrently, Mermaid uses an internal execution queue to serialize calls. Each call is enqueued and processed sequentially, preventing race conditions in the shared diagram registry and config state.

4.4 Registering External Diagrams

Third-party diagram types integrate through the ExternalDiagramDefinition interface:

await mermaid.registerExternalDiagrams([
  {
    id: 'custom-diagram',
    detector: (text) => text.startsWith('custom'),
    loader: () => import('./custom-diagram.js'),
  },
], { lazyLoad: true });  // lazyLoad: false loads immediately

The mermaid-example-diagram package serves as the reference implementation for building external diagram plugins.

4.5 Registering Layout Algorithms

Custom layout engines register through registerLayoutLoaders:

import { registerLayoutLoaders } from 'mermaid';

registerLayoutLoaders([
  {
    name: 'custom-layout',
    loader: () => import('./custom-layout.js'),
  },
]);

4.6 Docker-Based Development

The repository includes Docker support for the documentation site (packages/mermaid/src/docs/). The docs dev server can run inside Docker using pnpm dev:docker which binds to all interfaces (host 0.0.0.0) on port 3333.


5. Operations

5.1 Build Commands

Command Description
pnpm build Full build: esbuild + TypeScript declarations
pnpm build:esbuild Run esbuild only (all packages)
pnpm build:mermaid Build only the mermaid package
pnpm build:viz Build with bundle visualization
pnpm build:types Generate TypeScript declaration files
pnpm build:types:watch Watch mode for type declarations
pnpm dev Start esbuild dev server
pnpm dev:vite Start Vite dev server (for e2e)

5.2 Testing Commands

Command Description
pnpm test Lint + vitest run
pnpm ci vitest run (CI mode)
pnpm test:watch vitest watch mode
pnpm test:coverage vitest with V8 coverage
pnpm e2e Cypress end-to-end tests (starts dev server)
pnpm cypress:open Interactive Cypress runner
pnpm coverage Full coverage: unit + e2e + merge

5.3 Lint Commands

Command Description
pnpm lint eslint + jison lint + prettier check
pnpm lint:fix Auto-fix lint issues
pnpm lint:jison Lint jison grammar files only

5.4 Release Commands

Command Description
pnpm changeset:version Bump versions via changesets, rebuild, update docs
pnpm changeset:publish Copy README to mermaid package and publish
pnpm prepare husky setup + full build (runs on npm install)

5.5 Log Levels

The logger (packages/mermaid/src/logger.ts) supports six levels:

Level Value Console Method
trace 0 console.debug
debug 1 console.debug
info 2 console.info
warn 3 console.warn
error 4 console.error
fatal 5 console.error

Set via logLevel config key or numerically. Default is fatal (5) -- only fatal errors appear in the console. Each log message is prefixed with a timestamp (ss.SSS format) and level name.

5.6 Error Handling

Mermaid defines two custom error classes:

  • UnknownDiagramError -- Thrown when no detector matches the input text. Message: "No diagram type detected matching given configuration for text: {text}".
  • MermaidParseError -- Thrown by the Langium parser for syntax errors. Message: "Unknown diagram type: {diagramType}".

When suppressErrorRendering is false (default), parse errors cause a "Syntax error" diagram to be rendered in place of the failed diagram. Set suppressErrorRendering: true to prevent this behavior.

The setParseErrorHandler(fn) method provides a global error callback:

mermaid.setParseErrorHandler((err, hash) => {
  console.error('Mermaid parse error:', err);
});

6. Performance

6.1 Text Size Limits

The maxTextSize configuration (default: 50,000 characters) limits the input text length. The maxEdges configuration (default: 500) caps the number of edges in a single diagram. Both prevent denial-of-service through excessively large diagrams.

6.2 Layout Algorithm Selection

Algorithm Package Best For Tradeoffs
dagre (default) Built-in (dagre-d3-es) General-purpose graphs Fast, but limited control over node positioning
dagre-wrapper Built-in Flowcharts, class, state Enhanced dagre with cluster support and subgraph recursion
ELK @mermaid-js/layout-elk Complex graphs needing precise control Better quality for large graphs; heavier (~200KB elkjs); configurable strategies
CoSE-Bilkent Built-in (cytoscape) Force-directed layouts Good for organic layouts; less deterministic
Tidy Tree @mermaid-js/layout-tidy-tree Mindmaps Bidirectional tree layout optimized for hierarchical data

Tip

For large flowcharts (100+ nodes), switching from dagre to ELK layout often produces better results. Set layout: 'elk' in the config or via directive: %%{init: {"layout": "elk"}}%%.

6.3 Lazy Loading

Diagram type modules are lazy-loaded by default. The registerExternalDiagrams function accepts a lazyLoad option (default: true). When lazy-loading is enabled, diagram code is only fetched when a matching diagram definition is first encountered.

6.4 Deterministic Rendering

For stable diffs in version-controlled SVG output, enable deterministicIds: true with an optional deterministicIDSeed string. This replaces random UUIDs with sequential, reproducible identifiers using the InitIDGenerator class.

6.5 Bundle Size Optimization

The @mermaid-js/tiny package (v11.14.0) provides a minimal build variant that excludes less-common diagram types. For applications needing only specific diagrams, tree-shaking with the tiny build significantly reduces bundle size.


7. Security

7.1 Security Levels

Mermaid provides four security levels, controlled by securityLevel:

Level Behavior
strict (default) HTML tags in text are encoded. Click interactions disabled. All output sanitized.
loose HTML tags rendered as-is. Click interactions enabled. Output still sanitized via DOMPurify.
antiscript HTML tags allowed but script tags and event handlers stripped.
sandbox Diagram rendered inside a sandboxed <iframe> with sandbox attribute. Maximum isolation.

Caution

Setting securityLevel: 'loose' allows HTML rendering in diagram labels. Only use this in environments where you fully control the diagram input. User-submitted diagrams with loose security can execute XSS attacks despite DOMPurify sanitization.

7.2 HTML Sanitization

All rendered HTML/SVG passes through DOMPurify (dompurify ^3.3.1). The dompurifyConfig option allows passing custom DOMPurify configuration if the defaults are too restrictive or not restrictive enough.

7.3 URL Sanitization

URLs in diagrams (links, click handlers) are sanitized via @braintree/sanitize-url, which blocks javascript:, vbscript:, and data: protocol URLs.

7.4 Config Sanitization (Directive Protection)

The sanitize() function in config.ts provides three layers of protection against malicious directives (%%{init: {...}}%%):

  1. Secure key enforcement -- Keys in the secure array cannot be overridden by directives. By default: secure, securityLevel, startOnLoad, maxTextSize, maxEdges.

  2. Prototype pollution protection -- Any key starting with __ (double underscore) is silently deleted.

  3. XSS injection prevention -- String values containing <, >, or url(data: are deleted. This prevents SVG/HTML injection via directive values.

// Example: these directive values would be stripped
%%{init: {
  "fontFamily": "<script>alert('xss')</script>",  // stripped (contains <)
  "__proto__": {"polluted": true},                  // stripped (__ prefix)
  "securityLevel": "loose"                          // stripped (secure key)
}}%%

7.5 Additional Directive Sanitization

The sanitizeDirective() function (packages/mermaid/src/utils/sanitizeDirective.ts) provides a secondary sanitization pass for directives before they enter the config system, adding depth-limited traversal to prevent deeply nested attack payloads.

7.6 XSS Test Suite

The project maintains dedicated XSS tests:

  • cypress/integration/other/xss.spec.js -- End-to-end XSS regression tests
  • cypress/platform/xss*.html -- XSS test fixtures for manual and automated testing

Important

When integrating Mermaid into a CMS or user-facing application, always use securityLevel: 'strict' (the default) and ensure maxTextSize is set to a reasonable limit. Add the secure array to your initialize() call to lock down any additional config keys that users should not be able to override.

7.7 Content Security Policy (CSP)

When using securityLevel: 'sandbox', Mermaid creates an <iframe> with the sandbox attribute. For strict CSP environments:

  • style-src 'unsafe-inline' is required because Mermaid generates inline <style> elements for themes.
  • script-src must allow the Mermaid library source.
  • If using htmlLabels: true, <foreignObject> elements are inserted into SVG, which some CSP configurations may block.

8. Developer Internals

8.1 Diagram Plugin Architecture

To create a new diagram type, implement these four components:

// 1. Detector: regex that identifies your diagram type
export const detector = (text: string, config?: MermaidConfig): boolean => {
  return /^\s*myDiagram/.test(text);
};

// 2. Database: parse state management
export const db = {
  clear: () => { /* reset state */ },
  setDiagramTitle: (title: string) => { /* store title */ },
  getDiagramTitle: () => string,
  // ... domain-specific getters/setters
};

// 3. Renderer: SVG generation
export const renderer = {
  draw: async (text: string, id: string, version: string, diagram: Diagram) => {
    // Use d3 to create SVG elements
  },
};

// 4. Styles: CSS generator
export const styles = (options: any): string => {
  return `.node { fill: ${options.primaryColor}; }`;
};

// Bundle as DiagramDefinition
export const diagram: DiagramDefinition = { db, parser, renderer, styles };

Register with the detection system:

import { addDetector } from 'mermaid/diagram-api/detectType';

addDetector('myDiagram', detector, () =>
  import('./myDiagram').then(m => ({ id: 'myDiagram', diagram: m.diagram }))
);

8.2 Parser Architecture

Jison parsers (legacy):

Located in packages/mermaid/src/diagrams/{type}/parser/*.jison. These are Bison/Yacc-style grammars compiled to JavaScript at build time. The compiled parser attaches to parser.parser.yy which is set to the diagram's DB for direct state mutation during parsing.

Langium parsers (modern):

Located in packages/parser/src/language/{type}/. These use Langium's grammar language (.langium files) for type-safe AST generation. The @mermaid-js/parser package exports parser services for each diagram type. Langium parsers produce a typed AST rather than mutating a DB directly, then a transformer maps the AST to the DB format.

Current Langium-based diagrams: packet, info, pie (v2), gitGraph (v2), radar, architecture, wardley, treemap, treeView, eventmodeling, venn.

The common infrastructure shared between Langium parsers lives in packages/parser/src/language/common/:

  • CommonTokenBuilder (extends AbstractMermaidTokenBuilder) -- Shared tokenization logic
  • CommonValueConverter (extends AbstractMermaidValueConverter) -- Shared value conversion

8.3 Theme System

Mermaid ships 11 themes, implemented in packages/mermaid/src/themes/:

Theme Description
default Standard light theme
base Bare-bones theme designed for customization via themeVariables
dark Dark background with light text
forest Green-tinted nature theme
neutral Grayscale, suitable for printing
neo Modern light design
neo-dark Modern dark design
redux Simplified light theme
redux-dark Simplified dark theme
redux-color Simplified with color accents
redux-dark-color Dark with color accents

Each theme module exports a getThemeVariables(userOverrides?) function that returns a complete set of CSS variables. The base theme is specifically designed as a customization foundation -- set theme: 'base' and provide themeVariables to create a fully custom look:

mermaid.initialize({
  theme: 'base',
  themeVariables: {
    primaryColor: '#BB2528',
    primaryTextColor: '#fff',
    primaryBorderColor: '#7C0000',
    lineColor: '#F8B229',
    secondaryColor: '#006100',
    tertiaryColor: '#fff',
  },
});

Theme variables flow through the pipeline: initialize() passes themeVariables to the theme's getThemeVariables(), which computes derived colors (using the khroma library for color manipulation). The computed variables then feed into each diagram's styles() function to generate scoped CSS.

Note

The 'null' theme value (string "null") disables theming entirely. This is useful when you provide all styling via external CSS.

8.4 Layout System

The rendering pipeline supports pluggable layout algorithms through LayoutLoaderDefinition:

Dagre (default): The dagre layout engine (dagre-d3-es) operates in two paths:

  • Legacy dagre-wrapper (packages/mermaid/src/dagre-wrapper/) -- A recursive rendering implementation that handles subgraphs/clusters by recursively calling itself for nested graphs. This is the default for flowcharts, class diagrams, and state diagrams.
  • Unified layout path (packages/mermaid/src/rendering-util/layout-algorithms/dagre/) -- A newer integration point used by the layout algorithm abstraction.

The dagre-wrapper's recursiveRender() function is notable: it inserts nodes into the DOM to measure their dimensions, then runs dagre layout on the abstract graph, and finally positions the DOM elements. For cluster nodes, it calls itself recursively.

ELK (@mermaid-js/layout-elk): The ELK (Eclipse Layout Kernel) integration wraps elkjs for higher-quality layouts. It provides fine-grained control through the elk config namespace (node placement strategy, cycle breaking, model order preservation).

CoSE-Bilkent (packages/mermaid/src/rendering-util/layout-algorithms/cose-bilkent/): A force-directed layout using the Cytoscape.js ecosystem. Produces organic, spring-like layouts.

Tidy Tree (@mermaid-js/layout-tidy-tree): A bidirectional tree layout algorithm optimized for mindmaps and hierarchical data. Supports both top-down and left-right orientations.

8.5 Rendering Utilities

The packages/mermaid/src/rendering-util/ directory contains shared rendering infrastructure:

  • rendering-elements/ -- Shape rendering functions for 50+ node shapes (rectangles, diamonds, circles, hexagons, stadiums, cylinders, etc.), edge rendering, cluster rendering, and marker insertion.
  • layout-algorithms/ -- Layout algorithm implementations and abstractions.
  • render.ts -- Core render function and layout loader registry.
  • icons.ts -- Icon pack registration system (sync and async loaders for custom icon sets).

8.6 Accessibility

Mermaid includes built-in accessibility support (packages/mermaid/src/accessibility.ts):

  • SVG elements receive role="graphics-document document" (with ARIA 1.0 fallback).
  • aria-roledescription is set to the diagram type name.
  • accTitle and accDescription frontmatter directives generate <title> and <desc> elements with proper aria-labelledby/aria-describedby linkage.

8.7 Entity Encoding

Mermaid uses a custom entity encoding scheme to safely pass special characters through parsers. The encodeEntities() function in utils.ts converts HTML entities (e.g., #9829; for a heart) into an internal escape format (fl°°9829¶ß), which survives parser transformations and is decoded back during rendering.

8.8 Testing Strategy

Unit Tests (vitest):

Located alongside source files as *.spec.ts and in packages/parser/tests/. Run with pnpm test or pnpm ci. Coverage via @vitest/coverage-v8.

Key test patterns:

  • Config tests validate the three-tier config system, secure key enforcement, and directive handling.
  • Diagram tests verify parser output and DB state for each diagram type.
  • Accessibility tests use jsdom to verify SVG attributes.

End-to-End Tests (Cypress):

Located in cypress/integration/. Structure:

  • cypress/integration/rendering/ -- Visual regression tests for each diagram type.
  • cypress/integration/other/ -- XSS security tests, configuration tests.
  • cypress/platform/ -- HTML test fixtures including XSS regression pages.
  • cypress/helpers/ -- Shared test utilities.
  • cypress/support/ -- Cypress custom commands and setup.

Visual regression uses cypress-image-snapshot and Argos CI (@argos-ci/cypress) for screenshot comparison.

Tip

The project uses start-server-and-test to coordinate dev server startup with Cypress test execution. Run pnpm e2e for the full flow, or pnpm cypress:open for interactive test development.

8.9 Contributing: Development Workflow

  1. Clone and install:

    git clone https://github.com/mermaid-js/mermaid.git
    cd mermaid
    pnpm install
    
  2. Start dev server:

    pnpm dev
    
  3. Make changes in packages/mermaid/src/ or other packages.

  4. Run tests:

    pnpm test          # lint + unit tests
    pnpm e2e           # end-to-end tests
    
  5. Lint and format:

    pnpm lint:fix       # auto-fix eslint + prettier
    
  6. Build for production:

    pnpm build
    

Pre-commit hooks (managed by husky + lint-staged) automatically run linting on staged files.

8.10 State Management

The ImperativeState class (packages/mermaid/src/utils/imperativeState.ts) provides a pattern for diagram DB state that can be cleanly reset between renders. Each diagram DB uses this to maintain parse state (nodes, edges, actors, tasks, etc.) with a guaranteed-clean clear() method.

8.11 Interaction System

The interactionDb.ts module manages click handlers for interactive diagrams. Functions registered via addFunction() are executed by attachFunctions() after SVG insertion. In strict security level, click interactions are disabled.

8.12 Internal Helpers (Deprecated)

The internalHelpers export (packages/mermaid/src/internals.ts) exposes internal rendering functions for external diagram plugins. These are explicitly marked as deprecated and may change without notice:

export const internalHelpers = {
  common, getConfig, insertCluster, insertEdge,
  insertEdgeLabel, insertMarkers, insertNode,
  interpolateToCurve, labelHelper, log, positionEdgeLabel,
};

Caution

External diagram plugins currently depend on internalHelpers for rendering primitives. This coupling is a known technical debt. The mermaid team plans to provide a stable rendering API in a future version.


9. Integration Points

9.1 Public API Summary

The mermaid default export provides these methods:

Method Signature Description
initialize (config: MermaidConfig) => void Set site-wide configuration. Must be called before run.
run (options?: RunOptions) => Promise<void> Find and render all diagram elements in the DOM.
render (id: string, text: string, container?: Element) => Promise<RenderResult> Render a single diagram to SVG string.
parse (text: string, options?: ParseOptions) => Promise<ParseResult> Validate diagram syntax without rendering.
registerExternalDiagrams (diagrams: ExternalDiagramDefinition[], opts?) => Promise<void> Register third-party diagram types.
registerLayoutLoaders (loaders: LayoutLoaderDefinition[]) => void Register custom layout algorithms.
registerIconPacks (loaders: IconLoader[]) => void Register custom icon packs (sync or async).
contentLoaded () => void Trigger diagram rendering (called automatically on page load).
setParseErrorHandler (handler: (err, hash) => void) => void Set global parse error callback.

RunOptions:

interface RunOptions {
  querySelector?: string;  // Default: ".mermaid"
  nodes?: ArrayLike<HTMLElement>;  // Overrides querySelector
  postRenderCallback?: (id: string) => unknown;
  suppressErrors?: boolean;  // Default: false
}

ParseOptions and ParseResult:

interface ParseOptions {
  suppressErrors?: boolean;
}

interface ParseResult {
  diagramType: string;
}

RenderResult:

interface RenderResult {
  svg: string;
  bindFunctions?: (element: Element) => void;
}

9.2 Frontmatter and Directives

Mermaid diagrams support YAML frontmatter and inline directives for per-diagram configuration:

Frontmatter:

---
title: My Diagram
config:
  theme: dark
---
flowchart LR
  A --> B

Inline directive:

%%{init: {"theme": "forest", "flowchart": {"nodeSpacing": 100}}}%%
flowchart LR
  A --> B

The utils.detectInit(text) function extracts frontmatter and directive configurations, which are applied as directives to the current config.

9.3 Icon Packs

Custom icons can be registered for use in architecture diagrams and other icon-supporting diagram types:

// Synchronous loader
mermaid.registerIconPacks([
  {
    name: 'my-icons',
    loader: () => ({
      prefix: 'mi',
      icons: { server: { body: '<path d="..."/>', width: 24, height: 24 } },
    }),
  },
]);

// Asynchronous loader
mermaid.registerIconPacks([
  {
    name: 'remote-icons',
    loader: () => fetch('/icons.json').then(r => r.json()),
  },
]);

9.4 Webpack Integration

The tests/webpack/ directory provides a reference implementation for Webpack-based projects, demonstrating how to configure Webpack to bundle Mermaid correctly with its ESM dependencies.

9.5 VitePress Documentation Integration

The official documentation site (packages/mermaid/src/docs/) uses VitePress with:

  • unplugin-vue-components for auto-importing Vue components
  • unocss for utility-first CSS
  • vitepress-plugin-search for full-text search
  • A custom IncludesPlugin for file inclusion directives
  • A virtual module (virtual:mermaid-config) providing default Mermaid config for live examples

The docs dev server configuration aliases mermaid to the built distribution file (../../dist/mermaid.esm.min.mjs), ensuring docs render with the current build.

9.6 Known Issues

Issue Description
#3526 CSS classes not working with Flowchart v8.8.0+
#7609 Internal error on subgraph with numeric identifier
#6142 fontSize themeVariable setting ignored
#1361 ER diagram attributes (feature request)
#2199 Multi-line notes in sequence diagrams (feature request)

Warning

The flowchart.htmlLabels config is deprecated. Use the root-level htmlLabels setting instead. The root-level value always takes precedence. A deprecation warning is logged on first use of the flowchart-specific setting.