Mermaid
Render flowcharts, architecture and sequence diagrams across interfaces, documentation and reports.
On this page
Loading diagram…
Diagram source
flowchart LR
subgraph clients[Clients]
antique["<b>Antique</b>"]:::client
developers["<b>Developer machines</b>"]:::client
jobs["<b>CI and cluster jobs</b>"]:::client
end
server["<b>scion-server</b>"]:::service
daemon["<b>scion-daemon</b><br/>Per node"]:::service
cache["<b>scion-cache</b><br/>Regional"]:::service
spanner["<b>Spanner</b><br/>Changesets,<br/>branches, trees"]:::storage
storage["<b>Cloud Storage</b><br/>File contents"]:::storage
snapshot["<b>Periodic snapshot</b>"]:::storage
clients control@-->|"<b>Branches, history, diffs: upload, commit, land</b><br/><small>Control plane · every client</small>"| server
developers content1@-->|"<b>Trees and file contents</b><br/><small>Object plane</small>"| cache
jobs content2@--> daemon
daemon content3@-->|"<b>Misses</b>"| cache
cache content4@-->|"<b>Misses</b>"| server
server metadata@--> spanner
server files@--> storage
snapshot seed@-.->|"<b>Seeds new nodes</b>"| daemon
class content1,content2,content3,content4 dataflowCode
import type { ReactElement } from "react";
import { Mermaid, type MermaidLayout } from "@bosunkit/components/mermaid";
export const description: string =
"The supplied architecture reference, expressed as editable Mermaid with authored geometry: neutral clients and stores, blue services, contrasting content paths and a dashed snapshot dependency.";
// Coordinates describe the reference's diagram geometry, not CSS sizes. The shared renderer scales
// the complete drawing to the reading column and uses foundation tokens for every visual role.
const layout: MermaidLayout = {
width: 1200,
height: 512,
boxes: {
clients: { x: 39, y: 39, width: 231, height: 307, labelInset: [20, 11.5] },
antique: { x: 58, y: 110, width: 92, height: 48, labelInset: [12, 10] },
developers: { x: 58, y: 193, width: 192, height: 48, labelInset: [12, 10] },
jobs: { x: 58, y: 276, width: 176, height: 48, labelInset: [12, 10] },
server: { x: 752, y: 39, width: 169, height: 63, labelInset: [20, 16.5] },
daemon: { x: 296, y: 266, width: 185, height: 80, labelInset: [20, 12.5] },
cache: { x: 573, y: 159, width: 169, height: 187, labelInset: [20, 10.5] },
spanner: { x: 993, y: 39, width: 169, height: 100, labelInset: [20, 16] },
storage: { x: 993, y: 159, width: 169, height: 80, labelInset: [20, 16] },
snapshot: { x: 296, y: 411, width: 185, height: 62, labelInset: [20, 20] },
},
routes: {
control: {
points: [
[270, 70],
[733, 70],
],
label: { x: 296, y: 44.5, width: 440 },
},
content1: {
points: [
[250, 217],
[567, 217],
],
label: { x: 296, y: 188.5, width: 260 },
},
content2: {
points: [
[234, 300],
[290, 300],
],
},
content3: {
points: [
[481, 306],
[567, 306],
],
label: { x: 499, y: 273.1, width: 80 },
},
content4: {
points: [
[742, 261],
[837, 261],
[837, 109],
],
label: { x: 760, y: 228.1, width: 80 },
},
metadata: {
points: [
[921, 70],
[987, 70],
],
},
files: {
points: [
[921, 70],
[954, 70],
[954, 199],
[987, 199],
],
},
seed: {
points: [
[388, 411],
[388, 352],
],
label: { x: 323, y: 371, width: 145, mask: true },
},
},
};
export default function ReportArchitecture(): ReactElement {
return (
<Mermaid
label="Reference architecture. Clients use scion-server for branches, history and diffs. Developer machines retrieve content through scion-cache; cluster jobs use scion-daemon. Cache misses reach the server. A periodic snapshot seeds the daemon."
caption="Architecture from the supplied visual reference. Control connections are neutral, content paths contrast, and snapshot seeding is dashed."
layout={layout}
chart={`flowchart LR
subgraph clients[Clients]
antique["<b>Antique</b>"]:::client
developers["<b>Developer machines</b>"]:::client
jobs["<b>CI and cluster jobs</b>"]:::client
end
server["<b>scion-server</b>"]:::service
daemon["<b>scion-daemon</b><br/>Per node"]:::service
cache["<b>scion-cache</b><br/>Regional"]:::service
spanner["<b>Spanner</b><br/>Changesets,<br/>branches, trees"]:::storage
storage["<b>Cloud Storage</b><br/>File contents"]:::storage
snapshot["<b>Periodic snapshot</b>"]:::storage
clients control@-->|"<b>Branches, history, diffs: upload, commit, land</b><br/><small>Control plane · every client</small>"| server
developers content1@-->|"<b>Trees and file contents</b><br/><small>Object plane</small>"| cache
jobs content2@--> daemon
daemon content3@-->|"<b>Misses</b>"| cache
cache content4@-->|"<b>Misses</b>"| server
server metadata@--> spanner
server files@--> storage
snapshot seed@-.->|"<b>Seeds new nodes</b>"| daemon
class content1,content2,content3,content4 dataflow`}
/>
);
}
Mermaid is a shared diagram component under Charts and displays. Use it for system boundaries, processes and conversations wherever an editable drawing helps explain relationships. Use the same renderer in report pages and application interfaces.
Diagram style
The shared renderer uses spacious flowchart ranks, rounded boxes and connectors, quiet group panels and foundation typography. The diagram canvas has a rounded border and room around the drawing. Use a wide figure area for architecture diagrams, while keeping the explanation within a comfortable reading measure.
Use Mermaid subgraphs for system boundaries and label the connections with what moves between them. Dashed connections can show a different relationship, such as snapshot seeding; explain that distinction nearby.
The renderer supplies these optional classes from foundation diagram roles. No color values are needed in
the source. An authored classDef dataflow takes precedence over the connection preset.
| Class | Use | Appearance |
|---|---|---|
service | Named software services | Soft blue fill and outline; bold names use the code face |
client | People or client applications | Neutral outlined boxes |
storage | Durable stores and snapshots | Neutral outlined boxes, with an explicit role in the label |
dataflow | A named content path | Contrasting connector; retain a text label |
Loading diagram…
Diagram source
flowchart LR
client[Reader]:::client
service["<b>report-service</b><br/>Content delivery"]:::service
client content@-->|Report content| service
class content dataflowThe blue and contrasting connection colors follow the active theme, including the subdued Night palette.
A color is not a status or alert priority. Existing authored style, classDef and configuration remain part
of the source. Ordinary diagrams use Mermaid's automatic arrangement.
Authored layouts
Use the optional layout prop when an architecture diagram needs a deliberate composition like the hero above.
It describes a drawing width and height, boxes keyed by node/subgraph IDs, and connector routes keyed by explicit
edge IDs (content@-->). Coordinates are units within the drawing; the complete SVG scales to the page.
Labels, relationships, colors, line patterns and arrow types come from Mermaid and the shared renderer.
Each route supplies its ordered bend points and, when labeled, the label's top-left position and available width. The renderer rounds bends, preserves HTML line breaks and aligns labels to the left. Every rectangular node, subgraph and edge needs a placement. Unknown or missing IDs show the unavailable state with the source retained, so adding a node cannot silently hide it. Other diagram types use Mermaid's native layout and notation.
The hero's source panel includes its complete placement data. Source disclosure and Markdown exports retain the
Mermaid relationships; exact authored placement belongs to the JSX layout object. The reference's geometry and
palette guide the example. Foundation diagram type roles use a neutral sans serif for labels and the shared
code face for service names; diagram colors and spacing continue to follow the surrounding theme.
Details on nodes and lines
details lets a reader open what a node or a line stands for. Each entry is keyed as the source names it: a node by
its id (bosund), a line by its ends (bosund-->db, the first such line) or by its own id (content@-->). It opens
a tooltip on hover or focus, a popover beside it on a press, or a dialog for more than a few lines. Each gets a clear
target over its node, or over its line's label; a line without a label gets a round target on its middle. The targets
are buttons named by their titles, in the order of the keys, and follow the drawing when it is expanded or the page
is resized. A key that names nothing in the diagram gets no target. The diagram keeps its description, and
the relationships belong in nearby prose too.
Loading diagram…
Diagram source
flowchart LR
crew["Crew"] -->|"asks"| bosund["bosund"]
bosund -->|"replies"| crew
bosund --> db[(SQLite)]Code
import type { ReactElement } from "react";
import { Mermaid, type MermaidDetail } from "@bosunkit/components/mermaid";
export const description: string =
"A diagram whose parts open their details: point at or tab to bosund for a tooltip, press the Writes line or the " +
"Replies line for a popover, and press SQLite for a dialog.";
const CHART: string =
'flowchart LR\n crew["Crew"] -->|"asks"| bosund["bosund"]\n bosund -->|"replies"| crew\n bosund --> db[(SQLite)]';
const DETAILS: Readonly<Record<string, MermaidDetail>> = {
bosund: { open: "tooltip", title: "bosund", content: "The daemon on the vessel: voice, chat and every lookout." },
"crew-->bosund": { open: "popover", title: "Asks", content: "By voice at the helm, or in the chat on a phone." },
"bosund-->crew": { open: "popover", title: "Replies", content: "Spoken and written, usually within two seconds." },
"bosund-->db": { open: "popover", title: "Writes", content: "Readings to history.db, the ship's log to bosun.db." },
db: {
open: "dialog",
title: "SQLite",
content:
"Five files in the data directory: bosun.db for what the crew typed, history.db for what the instruments " +
"measured, cep.db, state.db and cache.db for what can be rebuilt.",
},
};
export default function Details(): ReactElement {
return <Mermaid label="The crew ask bosund, which replies and writes to SQLite." chart={CHART} details={DETAILS} />;
}
Decision flow
Loading diagram…
Diagram source
flowchart LR
Source[Source evidence] --> Review{Reviewed?}
Review -->|Yes| Report[Report]
Review -->|No| Followup[Follow-up]Code
import type { ReactElement } from "react";
import { Mermaid } from "@bosunkit/components/mermaid";
export const description: string = "An illustrative review flow, with source disclosure and expand/fit controls.";
export default function ReviewFlow(): ReactElement {
return (
<Mermaid
label="Evidence is reviewed before publication; incomplete evidence returns for follow-up."
chart={
"flowchart LR\n Source[Source evidence] --> Review{Reviewed?}\n Review -->|Yes| Report[Report]\n Review -->|No| Followup[Follow-up]"
}
/>
);
}
Markdown fences
Both sites register Fumadocs’ remarkMdxMermaid transform and the shared @bosunkit/components/mermaid renderer.
A fenced block and explicit JSX use the same component. No CDN or diagram service receives the source.
```mermaid
sequenceDiagram
participant Author
participant Reviewer
Author->>Reviewer: Evidence and draft
Reviewer-->>Author: Findings and questions
```Loading diagram…
Diagram source
sequenceDiagram
participant Author
participant Reviewer
Author->>Reviewer: Evidence and draft
Reviewer-->>Author: Findings and questionsThe reviewer receives the draft and its evidence, then returns findings and questions. For a specific accessible
name or a caption, use <Mermaid chart={source} label="Description of the relationships" caption="Source context" />.
Scoped themes
Loading diagram…
Diagram source
flowchart LR
Collect --> ReviewLoading diagram…
Diagram source
flowchart LR
Collect --> ReviewCode
import type { ReactElement } from "react";
import { PresentationScope } from "@bosunkit/provider";
import { Mermaid } from "@bosunkit/components/mermaid";
import { ReportGrid } from "@bosunkit/components/report-blocks";
export const description: string = "Independent Day and Night scopes use their own palettes on the same page.";
export default function DiagramScopes(): ReactElement {
return (
<ReportGrid>
<PresentationScope theme="day">
<Mermaid caption="Day scope" label="Day review flow" chart={"flowchart LR\n Collect --> Review"} />
</PresentationScope>
<PresentationScope theme="night">
<Mermaid caption="Night scope" label="Night review flow" chart={"flowchart LR\n Collect --> Review"} />
</PresentationScope>
</ReportGrid>
);
}
Night, Dusk, Day and Bright use foundation tokens. Explicit colors authored inside a diagram can override those roles; omit custom colors when the diagram should follow the site theme. Separate scopes render independently.
Inspection and unavailable states
Expand preserves the drawing’s natural width inside a horizontal scroll region. Fit returns it to the column. The controls are keyboard buttons and expose their pressed state. Print fits the drawing and hides the button. Malformed source shows a readable error and retains the source disclosure. Rendering uses Mermaid’s strict mode; do not rely on embedded HTML or diagram click handlers for essential content.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| chartrequired | string | – | Mermaid source with authored newlines. Rendered locally with strict security. |
| label | string | – | Accessible description of the diagram; a generic translated name is the fallback. |
| caption | string | – | Optional visible caption. Put detailed relationships in nearby prose too. |
| layout | MermaidLayout | – | Optional complete box/route geometry for rectangular flowcharts; IDs match the editable source. |
| details | Readonly<Record<string, MermaidDetail>> | undefined | – | What the reader can open from the diagram's nodes and lines, keyed as the source names them: a node by its id
(bosund), a line by its ends (bosund-->db, the first such line) or by its own id (content@-->). Each gets a
target over it, a button in the reading order of these keys; a key that names nothing in the diagram gets none. |
Publication follows review; incomplete evidence returns to its author.
Name each branch, keep source text and provide a nearby explanation.
Related
- Report blocks: linear pipelines and explained steps.
- Report figure: existing artwork and captions.
- Themes: display palettes and semantic roles.
- Fumadocs Mermaid: the Markdown transform contract.