Mermaid Diagrams Guide: Flowcharts, Sequence Diagrams, and More
Mermaid is Markdown for diagrams: you write plain text, and it renders an SVG. The diagram lives in a .md file or a fenced code block, travels through git with the rest of your code, and shows up rendered in pull requests, wikis, and documentation sites — no image files to commit, no Figma links to share, no exported PNGs going stale. Use the Mermaid Editor to follow along and experiment with every example in this guide.
Diagram Types at a Glance
| Keyword | Type | Best For |
|---|---|---|
flowchart / graph | Flowchart | Processes, decision trees, pipelines |
sequenceDiagram | Sequence | API calls, auth flows, message passing |
classDiagram | Class | OOP models, domain objects |
erDiagram | Entity-Relationship | Database schemas |
stateDiagram-v2 | State machine | UI states, lifecycle models |
gantt | Gantt chart | Project timelines, sprints |
pie | Pie chart | Proportions, quick breakdowns |
journey | User journey | UX flows with sentiment scores |
mindmap | Mind map | Brainstorming, topic hierarchies |
timeline | Timeline | Chronological events |
C4Context | C4 diagram | Software architecture (System/Container/Component) |
gitGraph | Git graph | Branch strategies, merge flows |
This guide focuses on the four types you will use daily: flowchart, sequenceDiagram, classDiagram, and erDiagram. The syntax patterns carry over to the others.
Flowchart Basics
Flowcharts start with flowchart (or the older alias graph) followed by a direction:
| Direction | Meaning |
|---|---|
TD | Top to bottom (default) |
LR | Left to right |
BT | Bottom to top |
RL | Right to left |
Node shapes are declared inline with bracket syntax around the label:
flowchart LR
A[Rectangle]
B(Rounded)
C{Diamond}
D>Asymmetric]
E((Circle))
F[(Database)]Connect nodes with arrows. Add a label by putting text between the dashes:
flowchart TD
Start([Start]) --> Validate{Valid input?}
Validate -- Yes --> Process[Process data]
Validate -- No --> Error[Return error]
Process --> Store[(Database)]
Store --> End([End])Arrow types give you more control: --> is a normal arrow, --- is a link without arrowhead, -.-> is a dotted arrow, and ==> is a thick arrow for emphasis. Subgraphs let you group nodes into named clusters:
flowchart LR
subgraph Client
Browser
end
subgraph Server
API --> DB[(Postgres)]
end
Browser -->|HTTP| APISequence Diagram Basics
Sequence diagrams show message exchange over time. Participants appear in the order they are declared or first mentioned:
sequenceDiagram
participant Browser
participant API
participant DB
Browser->>API: POST /login
API->>DB: SELECT user WHERE email=?
DB-->>API: user row
API-->>Browser: 200 OK + JWTArrow variants: ->> is a solid arrow (synchronous call), -->> is a dashed arrow (reply), -> is a solid line without arrowhead, and -x marks a lost message. Activations, loops, and conditional blocks make flows readable:
sequenceDiagram
actor User
participant Auth
participant API
User->>Auth: Login(email, password)
activate Auth
Auth->>API: Verify credentials
API-->>Auth: OK
deactivate Auth
loop Retry on timeout
User->>API: GET /data
end
alt Success
API-->>User: 200 data
else Unauthorized
API-->>User: 401
end
Note over User,API: All traffic is TLS-encryptedUse actor instead of participant to render a human figure icon — useful when distinguishing people from systems at a glance.
Class Diagram
Class diagrams model object-oriented structures. Declare a class with its members inside a block, then define relationships between classes:
classDiagram
class Animal {
+String name
+int age
+speak() String
}
class Dog {
+String breed
+fetch() void
}
class Cat {
-bool indoor
+purr() void
}
Animal <|-- Dog : inherits
Animal <|-- Cat : inherits
Dog "1" *-- "many" Toy : ownsVisibility modifiers follow UML convention:
| Symbol | Visibility |
|---|---|
+ | Public |
- | Private |
# | Protected |
~ | Package / internal |
Relationship arrows:
| Syntax | Relationship |
|---|---|
<|-- | Inheritance (is-a) |
*-- | Composition (owns) |
o-- | Aggregation (has) |
--> | Association |
..> | Dependency (uses) |
..|> | Realization (implements) |
ER Diagram
ER diagrams describe database schemas. Each entity is a table; relationships include cardinality on both ends:
erDiagram
USER {
int id PK
string email
string name
timestamp created_at
}
ORDER {
int id PK
int user_id FK
decimal total
string status
}
ORDER_ITEM {
int id PK
int order_id FK
int product_id FK
int quantity
}
PRODUCT {
int id PK
string name
decimal price
}
USER ||--o{ ORDER : places
ORDER ||--|{ ORDER_ITEM : contains
PRODUCT ||--o{ ORDER_ITEM : "referenced by"Cardinality syntax:
| Symbol | Meaning |
|---|---|
|| | Exactly one |
o| | Zero or one |
{} / o{ | Zero or many / One or many |
|{ | One or many |
Platforms That Render Mermaid
Mermaid has become a de facto standard in developer tooling. These platforms render fenced mermaid code blocks natively — no plugins required:
- GitHub — Markdown files, issues, pull request descriptions, and GitHub Pages all render Mermaid blocks as of 2022.
- GitLab — Supported in all Markdown contexts including wikis and merge request descriptions.
- Notion — Insert a code block, set the language to Mermaid, and it renders inline.
- Obsidian — Renders natively in preview mode; widely used for knowledge graphs and architecture notes.
- VS Code — The Markdown Preview Enhanced and Mermaid Preview extensions render diagrams in split view.
- Gitea / Forgejo — Supported in Markdown rendering since Gitea 1.13.
- Docusaurus, VitePress, MkDocs — Plugin or built-in support depending on version; diagrams live alongside documentation source.
To embed in any platform that renders GitHub-flavored Markdown, wrap your diagram in a fenced code block:
```mermaid
flowchart LR
A --> B --> C
```Configuration and Themes
Mermaid ships with five built-in themes: default, dark, forest, neutral, and base. Apply a theme with the init directive at the top of the diagram:
%%{init: {"theme": "dark"}}%%
flowchart TD
A --> BThe init directive also accepts themeVariables for fine-grained control over colors, font sizes, and node styles. You can set the theme globally in JavaScript when initializing Mermaid on your own page:
import mermaid from 'mermaid';
mermaid.initialize({
theme: 'neutral',
themeVariables: {
primaryColor: '#4f46e5',
primaryTextColor: '#fff',
lineColor: '#6b7280',
fontSize: '14px',
},
flowchart: {
curve: 'basis',
padding: 20,
},
});Docs-as-Code Workflow
The strongest argument for Mermaid over Figma or Lucidchart is version control. When your diagram is text, it:
- Diffs cleanly in pull requests. Reviewers see exactly which nodes or edges changed — not a binary blob comparison.
- Lives next to the code it describes. An
ARCHITECTURE.mdin the repository root, aREADME.mdin a service folder, or inline in API documentation — the diagram stays in sync with the code it documents because they are edited together. - Requires no external accounts. No Figma seats, no diagram export workflows, no broken share links.
- Auto-updates in generated docs. Documentation pipelines (Docusaurus, MkDocs, Sphinx with plugins) process Mermaid at build time, so the published site always reflects the latest diagram source.
A practical pattern: keep a docs/ directory in each service repository with Markdown files that include Mermaid diagrams for data flow, deployment topology, and state machines. Wire the CI pipeline to build and publish these docs on every merge to main. The diagrams are always current because updating them is a normal part of the PR that changes the code.
Rendering Outside Markdown Readers
Not every output target renders Mermaid natively. PDFs, Confluence pages, slide decks, and email newsletters need static images. The official CLI handles this:
# Install globally
npm install -g @mermaid-js/mermaid-cli
# Render to SVG (lossless, preferred for print)
mmdc -i diagram.mmd -o diagram.svg
# Render to PNG at a specific width
mmdc -i diagram.mmd -o diagram.png -w 1200
# Apply a theme
mmdc -i diagram.mmd -o diagram.svg -t dark
# Render with a custom CSS file
mmdc -i diagram.mmd -o diagram.svg --cssFile custom.cssThe input file is a plain text file containing only the Mermaid diagram source. Addmmdc to a CI job to export images as build artifacts for PDF documentation:
# .github/workflows/docs.yml (excerpt)
- name: Export Mermaid diagrams
run: |
npm install -g @mermaid-js/mermaid-cli
for f in docs/**/*.mmd; do
mmdc -i "$f" -o "${f%.mmd}.svg"
doneFor programmatic use in Node.js applications, import the mermaid package directly and call mermaid.render() to get an SVG string you can embed in HTML or convert to a PDF with a headless browser.
Common Gotchas
Mermaid syntax is forgiving until it is not. These are the issues that come up most often:
- Line breaks in labels. You cannot use a literal newline inside a node label. Use
<br/>to insert a line break:A["First line<br/>Second line"]. This only works in flowcharts, not in all diagram types. - Quotes inside labels. Double quotes delimit the label, so a literal quote inside the label breaks parsing. Escape it with the HTML entity
#quot;:A["He said #quot;hello#quot;"]. - Long labels wrap badly. Mermaid does not automatically wrap long labels. They overflow the node shape and collide with edges. Break long labels manually with
<br/>, shorten them, or use a note instead. - Reserved words as node IDs. Words like
end,class, andstyleare reserved in Mermaid syntax. Using them as node identifiers causes parse errors. Prefix them:endNode,classNode. - Syntax errors do not always point to the real line. Mermaid's error messages often report an error at the line after the actual mistake. If line 7 is flagged, check line 6.
- Indentation in subgraphs. Subgraph content must be indented consistently. Mixing tabs and spaces causes silent rendering failures where the subgraph renders empty.
- Percent signs in labels. A bare
%in a label can trigger comment parsing (%%starts a Mermaid comment). Escape it as#37;or rewrite the label to avoid it. - ER diagram relationship labels with spaces. Relationship labels containing spaces must be wrapped in double quotes:
USER ||--o{ ORDER : "places order".
The fastest way to isolate a syntax problem is to paste the diagram into the Mermaid Editor, which renders live and highlights errors as you type.
Mermaid covers the full range of diagrams that appear in software documentation — from a quick flowchart explaining a deploy pipeline to a full ER schema for a new service. Because the source is plain text, it travels with your code, reviews cleanly in pull requests, and never goes out of sync. For related tools, see the guides on Markdown to HTML and text processing tools.