All 30 Mermaid diagram types, parsed, laid out, and rendered in pure Swift — natively on macOS/iOS, Linux, Android, Windows, WebAssembly, and Flutter, plus any bare framebuffer or SDL surface, with byte-identical output.
A MermaidView follows light/dark automatically, sizes to the diagram, caches renders, and describes itself to VoiceOver. That's the whole integration.
.package( url: "https://github.com/2389-research/MermaidKit.git", from: "2.10.2" )
import MermaidRender MermaidView(""" flowchart TD A[Start] --> B{Choice} B -->|yes| C[Do it] B -->|no| D[Skip] """)
The platform-free layout core cross-compiles to every target; a fully-resolved scene crosses the C ABI as a language-neutral JSON contract (SceneWire), and each platform paints it with a thin native renderer. The scene's output is proven byte-identical across the five it compiles to — CI gates macOS, Linux, WASM and Windows on every PR and push to main, and Android was verified on an emulator — and a raw raster drives any bare surface beyond them.
macOS, iOS, Mac Catalyst, visionOS. MermaidView and the MermaidRenderer image/PDF/SVG API, drawn with CoreGraphics/CoreText.
Headless Cairo/FontConfig rendering behind the LinuxRaster trait; the platform-free layout runs anywhere Swift does.
MermaidDiagram("…", Modifier.fillMaxWidth()) — one line, themed from MaterialTheme, device-font measured, sized to the system font size, contentDescription from the narration. JNI over a per-ABI .so, shipped as an AAR.
MermaidNative.Scene("…") → new SceneRenderer().Draw(scene, canvas). Real Skia — the same engine as Android — over a P/Invoked Swift DLL. No SVG fallback. Pass textScale: the system's text scale factor for Dynamic Type.
MermaidNative.scene("…") → MermaidPainter on Flutter's Skia canvas, over dart:ffi on iOS, Android, and desktop; the painter itself draws a SceneWire scene on any Flutter target, web included. Pass textScale: from MediaQuery.textScalerOf (its multiplier at 12pt).
The core compiles to wasm32-unknown-wasi and emits SVG and the SceneWire scene — the layout engine, running anywhere WebAssembly does.
A raw RGBA raster with no display server drives a Raspberry Pi framebuffer (/dev/fb0), an SDL2 window, or a GPU texture — see tools/pi-canvas, an infinite pannable canvas.
A conformance harness runs the same fixtures on macOS, Linux, WebAssembly, and Windows in CI (and was run on an Android emulator) and asserts one signature. It caught two real cross-platform determinism bugs — and now gates them forever.
The class diagram is the real public API. The sankey hero is the render pipeline. The gitgraph is the actual release history. The same 30 files are the gallery, the lint corpus, and the benchmark suite at once — so the examples can't drift from what the engine does. Follows your system theme.






























Larger text is laid out larger: boxes, rows and the gaps labels sit in grow around it, while lines, arrowheads and markers keep their weight. That's different from scaling up a finished image, which thickens every line and blurs bitmaps. MermaidView follows Dynamic Type, Android's MermaidDiagram the system font size, and DiagramSpacing(textScale:) sets it anywhere, Flutter and .NET included. The default size is byte-identical to a render without it.

textScale: 1
textScale: 2MermaidView(source) // follows Dynamic Type MermaidRenderer.image(source: source, theme: theme, spacing: DiagramSpacing(textScale: 1.35)) // or pick a size
Every diagram lowers to a machine-readable geometry scene — boxes, edge routes, label frames. A geometry linter checks the invariants of good layout on every CI run and reports each failure as a named geometric fact, with coordinates.
A regression fails CI as "edge #3 is 165pt inside node DiagramScene" — a coordinate you can act on, not a pixel-diff image or a human squinting at a screenshot.
The same 30 fixtures are the gallery, the lint corpus, and the benchmark suite. The examples on this page cannot drift from what the engine actually does.
Geometry invariants run in CI, so a layout regression can't merge. Most tools rely on eyeballing or pixel snapshots that flake across fonts and OSes — checking geometry is stable, precise, and catches the real defect.
Layout is engineered underneath: network-simplex layer assignment (the strategy Graphviz dot defaults to), label-space reservation during layout, chain straightening after coordinate assignment, and edit-stability proven by scene-diff tests — rename a label to same-width text and nothing else moves.
MermaidView(source, theme:spacing:) — light/dark aware, self-sizing, cached, VoiceOver-described.
MermaidRenderer.image / pdfData / attachmentString — same layout and draw code; vector PDF for crisp export and print.
MermaidRenderer.svg(source:theme:) exports a standalone SVG document for all 30 types. It lowers through RenderScene — a Codable, platform-free render IR — whose SVGRenderer backend needs no drawing surface, so the scene → SVG path runs headless on Linux and in CI; projected to the SceneWire JSON contract, it feeds the shipped native Android, Windows, and Flutter renderers.
altText(source:) generates a deterministic content description for every one of the 30 types; MermaidAltText.narrate(_:) adds a step-by-step walkthrough — decisions, states, ER cardinalities, sequence messages. Diagram text follows Dynamic Type.
DiagramTheme — six colors plus a categorical palette re-skin all 30 types at once, and fontFamily sets every label in your app's font; DiagramSpacing sets density, and DiagramSpacing(gridSnap: 4) snaps flowcharts onto a pixel grid.
MermaidParser.diagnose(_:) explains failures with line numbers and did-you-mean suggestions for typo'd headers — and, for a flowchart that parses, notes each statement it left out, at its line.
CI parses 1,588 flowcharts with mermaid.js's own parser and with MermaidKit and compares what a reader sees; 1,330 agree, and a change that makes any chart read worse fails the build.
The parse → layout → scene pipeline is platform-free — no AppKit/UIKit. Tools get frames, polylines, and label boxes without rendering a pixel.
DOTParser, DippinParser, SQLDDLParser, and GitLogParser parse Graphviz DOT, Dippin, SQL CREATE TABLE, and raw git log output into the same engine; DOTExporter emits DOT back — a Mermaid ⇄ DOT converter. SQL DDL renders as an ER diagram with PK/FK/UK badges; git log renders as a gitgraph.
The mermaidkit-term CLI draws Mermaid, DOT, Dippin, and git log sources in the terminal — Kitty graphics or half-block truecolor for every type, colored or plain box-drawing for flowcharts. The box tiers are pure text and run headless on Linux/CI.
On Apple platforms, repeat renders hit an in-memory cache keyed by (source, theme, spacing). Input caps mirror mermaid.js — 50,000-character sources, 500 flowchart edges; oversized input returns nil fast. Requires Swift 6.2 / Xcode 26. Platforms: macOS 14+, iOS 17+, visionOS 1+, Linux (via the LinuxRaster package trait), and — via the platform-free scene core — Android, Windows/.NET, Flutter, and WebAssembly, plus any bare framebuffer or SDL/GPU surface.
Where the time goes: drawing (rasterization) is ~75% of a cold render; the parse-and-layout plumbing is lean, with a ~0.2 ms fixed floor. It's profiled, not guessed — the one "obvious" win, an 8-bit sRGB backing store, measured ~2× slower on Apple silicon, so it stayed f16. Full performance analysis →
Unknown dialects degrade to readable monospaced source. Styling directives are ignored, not fatal. Garbage, 100k-character labels, and NaN/Infinity are contained by an adversarial test suite with numeric sanitation at the parser boundary.
A dedicated "parser honesty" effort eliminated silent content loss and phantom content across the parsers — each fix pinned by a regression test using the exact previously-broken syntax. Flowcharts parse the forms coding agents actually emit: ids like api-gateway, {{hexagon}} and [[subroutine]], @{ shape: … } data, thick ==> and invisible ~~~ links, circle and cross heads, link lengths, and all 14 classic shapes.
The same platform-free layout core renders through native backends: CoreGraphics on Apple, Silica/Cairo on Linux, Kotlin Canvas on Android, SkiaSharp on Windows/.NET, a Dart CustomPainter on Flutter, and SVG on WebAssembly — with the scene's output proven byte-identical across the five it compiles to (four gated in CI, Android verified on an emulator), and a raw raster for any bare framebuffer/SDL surface.
The README states plainly what parses, what's ignored, and what's a known gap worth filing. SVG export now ships for all 30 types; lower OS floors sit at the top of the roadmap.
Guides, deep-dive engineering notes, and the full history — all on GitHub.