Tutorial8 min read

How to Create Mermaid Diagrams: Diagram-as-Code for Modern Docs

Mermaid lets you write diagrams as text that renders natively on GitHub, GitLab, Notion, and modern docs. Learn the syntax for the diagrams you'll actually need and where Mermaid falls short.

Mermaid lets you write diagrams as text. Instead of dragging boxes around in a graphical tool, you describe the diagram in a few lines of plain syntax and Mermaid renders it. The result lives in your repo, diffs cleanly in PRs, and renders natively on GitHub, GitLab, Notion, Obsidian, and most modern docs platforms. Here's how to actually use it well.

Why Diagram-as-Code?

Drawing tools like Lucidchart, Miro, and draw.io produce great-looking diagrams — but the source is a binary or a sprawling XML file. You can't easily review changes in a PR. You can't grep them. They drift out of sync with the code they describe.

Mermaid solves this:

  • Versioned. A .md or .mmd file is plain text — diff, blame, and review like any other file.
  • Embedded in docs. Mermaid renders inside a fenced code block on GitHub, GitLab, and most static site generators.
  • AI-friendly. LLMs can write and read Mermaid syntax fluently — both for generating diagrams from descriptions and for explaining what a diagram represents.
  • Platform-portable. The same source renders on multiple platforms with no export/import.

Diagram Types Mermaid Supports

Mermaid covers most documentation diagram needs:

Type Used For
Flowchart Decision trees, process flows
Sequence diagram API calls, user interactions over time
Class diagram OOP design, schema relationships
State diagram State machines, workflow states
ER diagram Database schemas
Gantt Project timelines
Pie chart Simple proportional data
Mindmap Hierarchical brainstorming
Git graph Branching strategies
C4 model Software architecture (context, container, component)
Timeline Historical events, roadmaps

You won't reach for Mermaid for pixel-perfect marketing diagrams. You'll reach for it constantly for "explain this system in a README" diagrams.

A Simple Flowchart

flowchart TD
    A[User submits form] --> B{Valid?}
    B -->|Yes| C[Save to DB]
    B -->|No| D[Show errors]
    C --> E[Send confirmation]

Breaking this down:

  • flowchart TD declares a top-down flowchart (LR for left-right).
  • A[...] defines a node. Square brackets = rectangle, curly braces {...} = diamond (decision), parentheses (...) = rounded.
  • A --> B is an arrow.
  • B -->|Yes| C puts a label on the arrow.

That's enough syntax to draw 80% of the flowcharts you'll ever write.

A Sequence Diagram

sequenceDiagram
    participant Client
    participant API
    participant DB

    Client->>API: POST /login
    API->>DB: SELECT user WHERE email=?
    DB-->>API: user record
    API->>API: verify password
    API-->>Client: 200 OK + JWT

Sequence diagrams are particularly powerful for documenting API flows or auth handshakes. The arrow types matter:

  • ->> solid arrow (synchronous call)
  • -->> dashed arrow (response)
  • -x solid with X (lost message)
  • --x dashed with X (lost response)

An ER Diagram

erDiagram
    USER ||--o{ ORDER : places
    ORDER ||--|{ ORDER_ITEM : contains
    PRODUCT ||--o{ ORDER_ITEM : "ordered as"

    USER {
        uuid id
        string email
        string name
        timestamp created_at
    }
    ORDER {
        uuid id
        uuid user_id
        decimal total
        string status
    }

The cardinality syntax (||--o{) reads as "exactly one to zero or more." Mermaid supports the full crow's-foot notation, which is more precise than the simple 1:N shorthand most diagramming tools use.

A State Diagram

stateDiagram-v2
    [*] --> Pending
    Pending --> Approved: approve
    Pending --> Rejected: reject
    Approved --> Shipped: ship
    Shipped --> Delivered: confirm
    Rejected --> [*]
    Delivered --> [*]

[*] represents the start (when on the left) or end (when on the right). Mermaid's state diagrams are great for documenting workflow states in a doc that lives next to the code that implements them.

How to Edit Mermaid Online

Use DevZone's Mermaid Editor to write and preview Mermaid diagrams interactively:

  1. Type your diagram syntax in the left pane.
  2. The right pane renders it live as you type.
  3. Pick a diagram type from the templates if you're starting fresh.
  4. Export as SVG or PNG for places that don't support Mermaid natively.
  5. Copy the source into your README, ADR, or doc.

The rendering happens in your browser using the official Mermaid library — diagrams aren't sent to a server.

Embedding Mermaid in Markdown

GitHub, GitLab, and Bitbucket render Mermaid in markdown automatically since 2022:

```mermaid
flowchart LR
    A --> B
```

Just use a mermaid code fence. No extension, no plugin. The diagram renders in PR descriptions, READMEs, and issue comments.

For static site generators (Hugo, Jekyll, Astro, MDX), there's usually a Mermaid plugin or a built-in renderer. Notion and Obsidian also support Mermaid out of the box.

Where Mermaid Falls Short

Be honest about its limits:

  • Layout control is limited. Mermaid auto-layouts your diagram. You can nudge it (rank, direction, classes), but you can't drag a node to a specific pixel.
  • Complex diagrams get ugly. Past ~30 nodes, auto-layout produces dense or crossing-heavy diagrams. Break large diagrams into smaller ones.
  • Styling is limited. You can apply CSS-like classes, but you won't get the polish of a hand-laid-out Figma diagram.
  • Subgraphs are awkward. Nesting works but layout often disappoints.

For external-facing presentation diagrams (marketing pages, sales decks, executive presentations), you probably still want a graphical tool. For internal docs, ADRs, READMEs, and architecture overviews — Mermaid is hard to beat.

Tips for Readable Diagrams

Limit nodes per diagram. 5–15 nodes per flowchart is the sweet spot. More than that, split into multiple diagrams.

Use direction deliberately. TD (top-down) is best for decision trees and processes. LR (left-right) is best for sequences, pipelines, and timelines.

Label edges where it helps. A flowchart with labeled arrows tells a story. A flowchart with bare arrows shows boxes connected to other boxes.

Group with subgraphs. When several nodes belong together logically, wrap them in a subgraph to communicate the grouping visually.

Comment your source. Mermaid supports %% comments. Use them to explain why the diagram is structured this way, especially when it represents a real system that future readers will need to update.

FAQ

Does Mermaid render on GitHub?

Yes — natively, in any markdown file (README, issues, PRs, comments). Use a fenced code block with mermaid as the language.

How do I export a Mermaid diagram as PNG/SVG?

Use the online editor's export button, or use the mmdc CLI (@mermaid-js/mermaid-cli):

npx -p @mermaid-js/mermaid-cli mmdc -i diagram.mmd -o diagram.svg

SVG is preferable for docs (scales without blur) and PNG for places that don't render SVG.

Can I use custom colors and themes?

Yes, with %%{init: {'theme': 'forest'}}%% at the top of your diagram, or via theme variables (themeVariables) for fine-grained control. Available built-in themes include default, forest, dark, and neutral.

Is Mermaid the same as PlantUML?

Both are diagram-as-code, but they're different products with different syntax. PlantUML is older, has a wider diagram library, and renders on the server (via a Java backend). Mermaid is JavaScript-based, renders client-side, and has tighter integration with markdown ecosystems. Mermaid has won in modern developer tooling; PlantUML still dominates in enterprise / Java shops.

Can I include Mermaid in PDFs?

Indirectly. Render the diagram to SVG/PNG with the CLI, then include the image in the PDF. Direct PDF generators that support Mermaid (Pandoc with the right filter, Typst with a plugin) exist but require setup.

Try the tools