mrkeyoor.com_
Sun 20 Sept 17:55 UTC
npmWeb Frontendupdated 20 Sept 2026

mermaid review

Mermaid 11.17.2 parses text definitions for flowcharts, sequence diagrams, class models, ER diagrams, state machines, Gantt charts, and other technical drawings, then produces SVG. The source can live beside Markdown and GitHub renders Mermaid code fences itself. The 11.17 line moved class diagrams to the unified v2 renderer and added collapsible flowchart subgraphs; 11.17.2 restores the edgePaths class used by flowchart, block, and user-journey styling.

Verdict

Mermaid 11.17.0 pulled 108 packages and produced a 925.2 KB gzipped browser bundle in our sandbox, so client-side rendering is a deliberate product cost, not a casual Markdown enhancement. Use 11.17.2 for editable diagram source, but pre-render SVG when readers do not need live generation and isolate untrusted diagrams.

We installed it

Lab card: what happened when we installed mermaidScreenshot of mermaid documentation
Install✓ · 8.2s108 packages on disk · 155 MB
ImportESM import works · require() works · ESM package with exports map
Browser925.2 KBgzipped (3371 KB minified), bundled with esbuild
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does mermaid install cleanly?

Yes. In a fresh container with an empty cache, npm install mermaid finished in 8 seconds, leaving 108 packages and 155 MB on disk. npm audit reported no known vulnerabilities.

How much does mermaid add to a browser bundle?

925.2 KB gzipped (3371 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does mermaid work with both ESM and CommonJS?

Yes. Both import 'mermaid' and require('mermaid') worked in Node 22 in our run. The package is published as ESM with an exports map.

Does mermaid include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

mermaid or cytoscape: which should you use?

cytoscape: Use it for interactive graph exploration with direct control over elements, events, and layouts. Mermaid 11.17.0 pulled 108 packages and produced a 925.2 KB gzipped browser bundle in our sandbox, so client-side rendering is a deliberate product cost, not a casual Markdown enhancement.

When should you not use mermaid?

Static SVG can be produced during the build; our broad 11.17.0 browser import measured 925.2 KB gzipped, which is expensive for readers who only view a diagram

API stability4/5initialize(), run(), render(), and parse() remain the core JavaScript surface in Mermaid 11.17.2. Syntax additions usually preserve those calls, but visual output is less stable than the API: the 11.17 line changed the default class-diagram renderer and the 11.17.2 patch restored an SVG class used by multiple stylesheets. Treat renderer upgrades like visual changes.
Docs4/5The official site has a syntax page for each diagram family, configuration references, live examples, integration guides, and a security section that discusses sandbox mode. Browser lifecycle details are less centralized: font loading, hidden containers, React effects, and server rendering require reading several pages or integration examples. The Live Editor is useful for confirming grammar before code integration.
Maintenance5/5npm served 11.17.2 on 2026-08-25, and GitHub showed a push on 2026-08-26. The unarchived repository had 89,952 stars and 1,737 open issues and pull requests when checked. The latest patch corrects SVG class output only days after the wider 11.17 release, evidence of active maintenance across a very large diagram and renderer surface.
Ecosystem5/5npm counted 15,046,097 downloads from 2026-08-19 through 2026-08-25. GitHub renders Mermaid fences natively, while the project also supplies a CLI, parser packages, optional ELK layouts, editor tooling, and numerous documentation integrations. That reach makes source portable even when a site decides to generate SVG during its build.

Use it if

  • Diagram source should be diffed and reviewed in the same repository as the documentation
  • A documentation system needs several diagram grammars behind one renderer
  • Authors already publish Mermaid code fences through GitHub or another compatible Markdown host
  • The application needs generated SVG and can control the theme, source, and rendering lifecycle
Skip it if

Setup reality

We installed Mermaid 11.17.0 in 8.2 seconds under Node 22. The clean environment contained 108 packages using 155 MB, and npm audit reported 0 vulnerabilities at every severity. Mermaid declared 22 direct dependencies and 0 peers, occupied 85,796 KB unpacked, and included TypeScript declarations. It is an ESM package with an exports map; both require() and ESM import worked in our sandbox.

Mermaid needs no credentials. Call initialize once with startOnLoad, securityLevel, theme, and size limits chosen for the application. Per-diagram directives can change settings. Treat that ability as part of the input surface and do not combine unknown user diagrams with loose security. The project recommends sandboxed iframe rendering for externally supplied text.

render() measures text through the DOM, so missing fonts and display:none containers can produce bad node boxes. React code belongs in a client component with a unique SVG ID and a stale-promise guard because StrictMode may repeat an effect. The CLI uses a headless browser for build-time SVG, which also means CI must provide consistent fonts for stable snapshots.

Our full namespace esbuild import of 11.17.0 produced 3,371 KB minified and 925.2 KB gzipped. Lazy loading delays that cost but does not erase rendering work. Version 11.17.2 is now current and restores the edgePaths class used by several stylesheets. Test CSS selectors and visual snapshots when moving within 11.17, especially if the application depended on the previous class-diagram renderer.

Patterns

Render source into one container render-svg

import mermaid from 'mermaid';

mermaid.initialize({ startOnLoad: false, securityLevel: 'strict' });
const host = document.querySelector('#graph');
const { svg, bindFunctions } = await mermaid.render(
  'graph-1',
  'flowchart LR\n  a[Start] --> b{Ok?}\n  b -->|yes| c[Done]',
);
host.innerHTML = svg;
bindFunctions?.(host);

Each render needs a unique ID. Insert the returned SVG before bindFunctions attaches any generated interactions.

Process existing Mermaid elements render-page-blocks

import mermaid from 'mermaid';

mermaid.initialize({ startOnLoad: false });
await mermaid.run({ querySelector: '.mermaid' });

await mermaid.run({
  nodes: document.querySelectorAll('.mermaid:not([data-processed])'),
});

run marks successful nodes with data-processed. To rerender changed source, restore the text and clear that marker first.

Validate grammar before rendering parse-source

const parsed = await mermaid.parse(source, { suppressErrors: true });
if (parsed === false) {
  showEditorError('Invalid Mermaid source');
} else {
  console.log(parsed.diagramType);
}

suppressErrors returns false for a parse failure. Configure error rendering separately if the application must own all failure UI.

Render inside a React client component render-react

'use client';
import { useEffect, useId, useState } from 'react';
import mermaid from 'mermaid';

export function Diagram({ chart }) {
  const id = useId().replace(/:/g, '');
  const [svg, setSvg] = useState('');
  useEffect(() => {
    let stale = false;
    mermaid.render('m-' + id, chart).then((result) => {
      if (!stale) setSvg(result.svg);
    });
    return () => { stale = true; };
  }, [chart, id]);
  return <div dangerouslySetInnerHTML={{ __html: svg }} />;
}

StrictMode can begin 2 renders in development. A stable ID and stale-result guard keep the older promise from replacing new source.

Configure one base theme set-theme

mermaid.initialize({
  startOnLoad: false,
  theme: 'base',
  themeVariables: {
    primaryColor: '#101418',
    primaryTextColor: '#e6e6e6',
    lineColor: '#5b6472',
    fontFamily: 'ui-sans-serif, system-ui, sans-serif',
  },
  flowchart: { curve: 'basis', htmlLabels: true },
});

Theme variables are designed around the base theme. Initialize once so later calls do not leave global configuration in an uncertain state.

Apply a per-diagram directive configure-diagram

const chart = "%%{init: {'theme':'base','themeVariables':{'lineColor':'#ff6b6b'}}}%%\nsequenceDiagram\n  Client->>Server: subscribe\n  Server-->>Client: ack";
const { svg } = await mermaid.render('seq-1', chart);

An init directive changes rendering configuration from source text. Permit it only where the author is allowed to control those options.

Bind a flowchart node action add-click-action

mermaid.initialize({ startOnLoad: false, securityLevel: 'loose' });
window.openService = (id) => router.push('/services/' + id);

const chart = "flowchart TD\n  api[API] --> db[(Postgres)]\n  click api call openService('api')";
const { svg, bindFunctions } = await mermaid.render('svc', chart);

Callbacks require loose security and a function on window. Do not enable this mode for diagrams supplied by unknown users.

Bound source and edge work limit-input

mermaid.initialize({
  startOnLoad: false,
  maxTextSize: 50_000,
  maxEdges: 500,
});

if (source.length > 50_000) {
  throw new Error('Diagram source is too large');
}

Layout can occupy the main thread. Split an oversized graph or pre-render it instead of raising limits until the page stalls.

Register ELK layouts load-elk

import mermaid from 'mermaid';
import elkLayouts from '@mermaid-js/layout-elk';

mermaid.registerLayoutLoaders(elkLayouts);
mermaid.initialize({ startOnLoad: false, layout: 'elk' });

ELK adds code and layout work, and only supported diagram families use it. Compare the graph you actually publish.

Register architecture icons lazily load-icon-pack

mermaid.registerIconPacks([{
  name: 'logos',
  loader: () =>
    fetch('/icons/logos.json').then((response) => response.json()),
}]);

Rendering waits for the icon loader. Self-host or cache the JSON when a remote failure must not leave placeholders.

Make generated IDs repeatable stabilize-snapshots

mermaid.initialize({
  startOnLoad: false,
  deterministicIds: true,
  deterministicIDSeed: 'snapshot',
});

const { svg } = await mermaid.render('fixture', chart);

A fixed seed stabilizes internal IDs. Fonts, layout engines, and Mermaid patches can still change the SVG geometry.

Generate SVG during the build render-cli

npx -p @mermaid-js/mermaid-cli mmdc \
  -i docs/architecture.mmd \
  -o docs/architecture.svg \
  -b transparent -t dark

The CLI launches headless Chromium for DOM measurement. Pin its package and browser, then install the same fonts in CI for repeatable output.

Alternatives

PackageRegistryPick it when
cytoscapenpmUse it for interactive graph exploration with direct control over elements, events, and layouts
dagre-d3npmUse it when one directed-graph layout plus D3 rendering is enough and Mermaid's many grammars are excess
plantuml-encodernpmUse it when PlantUML source and an existing external rendering service define the documentation flow

More web frontend guides

postcss · react · react-dom · tailwindcss · htmlparser2 · tailwind-merge · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.