DevToys Web Pro iconDevToys Web ProBlogi
Käännetty LocalePack logoLocalePack
Arvostele meidät:
Kokeile selainlaajennusta:
← Back to Blog

Mermaid Diagrams Guide: Flowcharts, Sequence Diagrams, and More

11 min read

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

KeywordTypeBest For
flowchart / graphFlowchartProcesses, decision trees, pipelines
sequenceDiagramSequenceAPI calls, auth flows, message passing
classDiagramClassOOP models, domain objects
erDiagramEntity-RelationshipDatabase schemas
stateDiagram-v2State machineUI states, lifecycle models
ganttGantt chartProject timelines, sprints
piePie chartProportions, quick breakdowns
journeyUser journeyUX flows with sentiment scores
mindmapMind mapBrainstorming, topic hierarchies
timelineTimelineChronological events
C4ContextC4 diagramSoftware architecture (System/Container/Component)
gitGraphGit graphBranch 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:

DirectionMeaning
TDTop to bottom (default)
LRLeft to right
BTBottom to top
RLRight 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| API

Sequence 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 + JWT

Arrow 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-encrypted

Use 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 : owns

Visibility modifiers follow UML convention:

SymbolVisibility
+Public
-Private
#Protected
~Package / internal

Relationship arrows:

SyntaxRelationship
<|--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:

SymbolMeaning
||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 --> B

The 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.md in the repository root, a README.md in 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.css

The 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"
    done

For 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, and style are 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.