Gagan Thakur·

The Complete Mermaid.js Tutorial: All Diagram Types with Examples (2026)

Master every Mermaid.js diagram type in one guide. Flowcharts, sequence diagrams, class diagrams, ER, Gantt, state, mindmaps, Git graphs, and more — with copy-paste examples and best practices.

# The Complete Mermaid.js Tutorial: All Diagram Types with Examples (2026)

Mermaid.js is the fastest way to create professional diagrams from plain text. This guide covers every major diagram type with working examples you can copy directly into the Mermaid Live Editor or paste into GitHub markdown.

Whether you are documenting a system architecture, planning a sprint, modeling a database schema, or mapping a user journey — Mermaid has a diagram type for it.

What is Mermaid.js?

Mermaid.js is an open-source JavaScript library that renders text-based diagram definitions into SVG graphics. The idea is simple: instead of dragging boxes in a GUI tool, you describe your diagram in plain text. Mermaid converts that text into a clean, publication-quality diagram.

Why this matters:

  • Version control — diagram source is text, so it lives in git alongside your code
  • No GUI friction — type the diagram instead of clicking around
  • Native platform support — GitHub, GitLab, Notion, Obsidian, Confluence, and VS Code all render Mermaid natively
  • Zero install for readers — embed in any markdown file; the platform renders it
  • Collaboration — diffs show exactly what changed in a diagram, just like code

Mermaid was created by Knut Sveidqvist in 2014 and is now one of the most starred developer tools on GitHub, with active development and broad ecosystem adoption.

Getting Started in 60 Seconds

The fastest way to try Mermaid is in a free online editor. Paste any code from this tutorial into mermaideditor.lol and see it render instantly — no sign-up, no install.

Every Mermaid diagram starts with a diagram type keyword on the first line:

flowchart TD
    A[Start] --> B[End]
Try in Editor →

That is a complete, valid flowchart. The keyword flowchart TD tells Mermaid the diagram type (flowchart) and layout direction (top-down). Everything after that follows the rules for that diagram type.

To embed in GitHub or GitLab markdown, use a fenced code block tagged mermaid:

    ```mermaid
    flowchart TD
        A --> B
    ```

Flowcharts

Flowcharts are the most versatile diagram type in Mermaid. Use them for processes, decision trees, CI/CD pipelines, user flows, system architectures, and anything with steps, branches, and connections.

Direction

flowchart TD   %% Top → Bottom
flowchart LR   %% Left → Right
flowchart BT   %% Bottom → Top
flowchart RL   %% Right → Left
Try in Editor →

You can also use the older graph keyword (graph TD, graph LR) — it is identical.

Node Shapes

flowchart TD
    A[Rectangle]
    B(Rounded Rectangle)
    C([Stadium])
    D[[Subroutine]]
    E[(Cylinder / Database)]
    F((Circle))
    G{Diamond / Decision}
    H{{Hexagon}}
    I>Flag / Ribbon]
    J[/Parallelogram/]
Try in Editor →

The shape syntax comes from the bracket type wrapping the label:

- Square brackets [] → rectangle

- Parentheses () → rounded

- Double parens (()) → circle

- Curly braces {} → diamond

- Cylinder: [()]

Edge (Arrow) Types

flowchart LR
    A --> B        %% Solid arrow
    C --- D        %% Line, no arrow
    E -.-> F       %% Dotted arrow
    G ==> H        %% Thick arrow
    I --o J        %% Circle end
    K --x L        %% Cross end
    M -->|label| N %% Arrow with label
    O -.->|note| P %% Dotted with label
Try in Editor →

Subgraphs

Group related nodes into named boxes:

flowchart TB
    subgraph frontend["Frontend"]
        direction LR
        React --> Redux
        Redux --> API_client
    end
    subgraph backend["Backend"]
        direction TB
        API_server --> Database
        API_server --> Cache
    end
    frontend --> backend
Try in Editor →

Note: Each subgraph can have its own direction — independent of the outer flowchart direction.

Real-World Example: CI/CD Pipeline

flowchart LR
    A([Push to GitHub]) --> B[Run Linter]
    B --> C[Unit Tests]
    C --> D{All Pass?}
    D -->|No| E[Notify Developer]
    D -->|Yes| F[Build Docker Image]
    F --> G[Push to Registry]
    G --> H{Branch?}
    H -->|main| I[Deploy Production]
    H -->|develop| J[Deploy Staging]
    J --> K[Run E2E Tests]
Try in Editor →

Sequence Diagrams

Sequence diagrams show time-ordered interactions between actors and systems. They are the go-to diagram for API documentation, authentication flows, microservice communication, and any scenario where the *order* of messages matters.

Basic Syntax

sequenceDiagram
    participant C as Client
    participant A as API
    participant D as Database

    C->>A: GET /users
    A->>D: SELECT * FROM users
    D-->>A: rows
    A-->>C: 200 OK [JSON]
Try in Editor →

Arrow types for sequences:

- ->> solid arrow (synchronous call)

- -->> dotted arrow (response / return)

- -) open async arrow (fire and forget)

- -x cross (message lost or error)

Activation Bars

Show when a participant is actively processing:

sequenceDiagram
    Client->>+Server: POST /orders
    Server->>+Database: INSERT order
    Database-->>-Server: order_id=42
    Server-->>-Client: 201 Created {id: 42}
Try in Editor →

The + and - on message arrows activate/deactivate the recipient.

Control Flows

sequenceDiagram
    autonumber

    loop Retry (max 3)
        Client->>API: Fetch data
    end

    alt Cache hit
        API-->>Client: Cached response
    else Cache miss
        API->>DB: Query database
        DB-->>API: Results
        API-->>Client: Fresh response
    end

    opt Debug mode enabled
        API->>Logger: Log request
    end

    par Parallel notifications
        API->>Email: Send email
    and
        API->>SMS: Send SMS
    end
Try in Editor →

Real-World Example: OAuth 2.0

sequenceDiagram
    actor User
    participant App
    participant AuthServer as Auth Server
    participant API as Resource Server

    User->>App: Click "Login with Google"
    App->>AuthServer: Redirect to /authorize
    AuthServer->>User: Consent screen
    User->>AuthServer: Grant access
    AuthServer-->>App: Authorization code
    App->>+AuthServer: POST /token
    AuthServer-->>-App: access_token + refresh_token
    App->>+API: GET /me (Bearer token)
    API-->>-App: User profile
    App-->>User: Logged in ✓
Try in Editor →

Class Diagrams

Class diagrams model object-oriented structure: classes, interfaces, enums, their attributes, methods, and relationships. Useful for design documentation, code reviews, and communicating architecture.

Class Syntax

classDiagram
    class Vehicle {
        +String make
        +String model
        -int year
        #float price
        +start() void
        +stop() void
        +getInfo()$ String
    }
Try in Editor →

Visibility modifiers:

- + public

- - private

- # protected

- ~ package/internal

- $ static method (append to method name)

- * abstract method (append to method name)

Relationships

classDiagram
    Animal <|-- Dog         : Inheritance
    Car *-- Engine          : Composition
    Library o-- Book        : Aggregation
    Teacher --> Student     : Association
    Printer ..> Document    : Dependency
    Shape ..|> Drawable     : Realization
    Dog "1" --> "*" Paw     : Cardinality
Try in Editor →

Design Pattern Example: Repository

classDiagram
    class Repository~T~ {
        <<interface>>
        +findById(id) T
        +findAll() List~T~
        +save(entity T) T
        +delete(id) void
    }
    class UserRepository {
        -db: Database
        +findById(id) User
        +findAll() List~User~
        +findByEmail(email) User
        +save(user) User
        +delete(id) void
    }
    class User {
        +int id
        +String email
        +String passwordHash
        +boolean active
    }

    Repository <|.. UserRepository
    UserRepository --> User : manages
Try in Editor →

State Diagrams

State diagrams model finite state machines — the set of all possible states an entity can be in, and the transitions that move it between them. Unlike flowcharts (which show a process that runs once from start to end), state diagrams model something that *persists* and changes over time in response to events.

Use state diagrams for:

  • Order and payment lifecycles — Draft → Submitted → Processing → Shipped → Delivered
  • User authentication — Unauthenticated → Authenticating → Authenticated → SessionExpired
  • UI component states — Idle → Loading → Success / Error → Idle
  • Protocol implementations — TCP connection states, WebSocket lifecycle
  • Subscription billing — Trialing → Active → PastDue → Cancelled

The key concepts: every machine starts at the initial state ([*]), ends at the final state ([*]), and transitions happen when an event occurs (the label on the arrow). Guards (conditions) can be added to transitions to control when they fire.

stateDiagram-v2
    direction LR
    [*] --> Draft

    Draft --> PendingApproval : submit()
    PendingApproval --> Approved : approve()
    PendingApproval --> Rejected : reject()
    PendingApproval --> Draft : requestChanges()
    Approved --> Published : publish()
    Published --> Archived : archive()
    Rejected --> [*]
    Archived --> [*]

    note right of PendingApproval
        Notifies reviewer
        by email
    end note
Try in Editor →

Nested / Composite States

stateDiagram-v2
    [*] --> Idle

    state Authenticated {
        [*] --> Idle
        Idle --> Loading : fetch()
        Loading --> Idle : done
        Loading --> Error : failed
        Error --> Idle : retry()
    }

    [*] --> Authenticated
    Authenticated --> [*] : logout()
Try in Editor →

Concurrency (Fork/Join)

When two things happen simultaneously, use fork and join pseudo-states to show parallel execution:

stateDiagram-v2
    state fork <<fork>>
    state join <<join>>

    [*] --> fork
    fork --> ProcessPayment
    fork --> SendConfirmation
    ProcessPayment --> join
    SendConfirmation --> join
    join --> [*]
Try in Editor →

Fork splits execution into parallel branches. Join waits for all branches to complete before continuing. This is the state diagram equivalent of Promise.all().

Tip: If you are documenting a feature flag or A/B test, state diagrams are excellent for showing how the same trigger leads to different states depending on the cohort or condition.

Entity Relationship Diagrams

ER diagrams (Entity-Relationship diagrams) model database schemas — the tables, their columns, and how records in one table relate to records in another. Mermaid uses crow's foot notation, the same notation taught in database courses and used by tools like dbdiagram.io and MySQL Workbench.

ER diagrams are indispensable for:

  • Schema design reviews — communicate a proposed schema to the team before writing migrations
  • Onboarding documentation — help new engineers understand the data model fast
  • API design — the ER diagram and the API shape tend to mirror each other; modeling one clarifies the other
  • Database refactors — show before/after schema side by side

Attribute markers:

- PK — primary key

- FK — foreign key

- UK — unique constraint

- No marker — regular column

Relationships use crow's foot notation on both ends of the line. The left side describes the parent, the right side describes the child.

erDiagram
    CUSTOMER {
        int id PK
        string name
        string email UK
        datetime created_at
    }
    ORDER {
        int id PK
        int customer_id FK
        string status
        decimal total
        datetime placed_at
    }
    ORDER_ITEM {
        int id PK
        int order_id FK
        int product_id FK
        int quantity
        decimal unit_price
    }
    PRODUCT {
        int id PK
        string name
        string sku UK
        decimal price
        int stock
    }

    CUSTOMER ||--o{ ORDER : places
    ORDER ||--|{ ORDER_ITEM : contains
    PRODUCT ||--o{ ORDER_ITEM : included_in
Try in Editor →

Cardinality Reference

NotationMeaning
`--`exactly one to exactly one
`--o{`exactly one to zero or many
`--{`exactly one to one or many
`}o--o{`zero or many to zero or many

Solid line (--) = identifying relationship (child's PK includes parent's PK, e.g. ORDER_ITEM). Dashed line (..) = non-identifying (child has its own PK, just a FK reference).

Second Example: SaaS Multi-Tenant Schema

erDiagram
    WORKSPACE {
        int id PK
        string name
        string slug UK
        string plan
        datetime created_at
    }
    MEMBER {
        int id PK
        int workspace_id FK
        int user_id FK
        string role
    }
    USER {
        int id PK
        string email UK
        string password_hash
    }
    PROJECT {
        int id PK
        int workspace_id FK
        string name
        string status
    }
    TASK {
        int id PK
        int project_id FK
        int assignee_id FK
        string title
        string priority
        date due_date
    }

    WORKSPACE ||--o{ MEMBER : has
    USER ||--o{ MEMBER : belongs_to
    WORKSPACE ||--o{ PROJECT : owns
    PROJECT ||--o{ TASK : contains
    USER ||--o{ TASK : assigned
Try in Editor →

Notice the MEMBER junction table — it holds the many-to-many relationship between WORKSPACE and USER, plus the role that user has in that workspace. This pattern (pivot table with extra columns) is extremely common in SaaS schemas.

Gantt Charts

Gantt charts visualize project schedules — tasks, durations, dependencies, and milestones. Mermaid Gantt is excellent for sprint planning, release schedules, and roadmaps.

The most common use case is pasting a Gantt into a project RFC or kick-off document to communicate timeline at a glance. Because it is text-based, updating a date or duration is a one-second edit rather than a drag operation in a GUI tool.

gantt
    title Q2 2026 Roadmap
    dateFormat YYYY-MM-DD
    axisFormat %b %d
    excludes weekends

    section Discovery
    User research            :done, ur, 2026-04-01, 7d
    Competitive analysis     :done, ca, 2026-04-01, 5d
    Requirements sign-off    :milestone, m1, after ur ca, 0d

    section Development
    Backend API              :active, be, after m1, 14d
    Frontend                 :fe, after m1, 14d
    Integration              :int, after be fe, 5d

    section QA & Launch
    QA testing               :crit, qa, after int, 7d
    Security audit           :crit, sec, after int, 5d
    Production deploy        :milestone, crit, prod, after qa sec, 0d
Try in Editor →

Task state modifiers (combine freely with commas):

- done — completed, rendered gray

- active — in progress, highlighted

- crit — on critical path, rendered red

- milestone — zero-duration marker, rendered as a diamond

Dependency syntax: after task1 task2 starts the current task only after BOTH task1 AND task2 complete. This is how you model parallel work streams that converge.

Date formats: dateFormat controls how Mermaid parses your date strings. Common values: YYYY-MM-DD, DD/MM/YYYY, MM-DD-YYYY. axisFormat controls how dates display on the horizontal axis: %b %d (Jan 01), %b (Jan), %Y (2026).

Excluding dates: excludes weekends skips Saturday and Sunday automatically. You can also exclude specific dates: excludes weekends, 2026-12-25, 2027-01-01.

Task ID reuse: Give tasks IDs (done, t1, 2026-01-01, 5d) so other tasks can reference them with after t1. Without IDs, dependencies cannot be expressed.

Mind Maps

Mindmaps visualize hierarchical information through a tree structure radiating from a central root. They are the fastest diagram type to write — indentation is the entire syntax. One level of indent = one level deeper in the tree.

Use mindmaps for:

  • Brainstorming — capture ideas fast without worrying about arrows or connections
  • Topic outlines — planning a blog post, course, or documentation section
  • Feature breakdowns — decomposing an epic into stories and tasks
  • Learning paths — mapping what someone needs to learn to reach a goal
  • Stakeholder mapping — who is affected and how

The root node uses double parentheses for a circle shape: root((Central Topic)). Child nodes are plain text. Deeper children are indented further — Mermaid handles the layout automatically.

mindmap
    root((Mermaid.js))
        Diagram Types
            Flowchart
            Sequence
            Class
            State
            ER
            Gantt
            Mindmap
            Git Graph
            Timeline
        Where to Use
            GitHub README
            Notion / Confluence
            VS Code
            Obsidian
        Tools
            mermaideditor.lol
            Mermaid Live Editor
            CLI
        Export
            SVG
            PNG
Try in Editor →

Git Graphs

Git graphs visualize branch strategies and commit histories. They are uniquely useful for developer-facing documentation: contributing guides, release process docs, GitFlow explanations, and hotfix procedures. Instead of embedding a screenshot of a git log, you write the graph as text and it stays accurate when someone edits it.

Unlike other diagram types, git graphs always render horizontally (left to right = oldest to newest). Every commit is a dot on a branch line. Merges draw an arrow from source to destination branch at the merge point.

Supported operations: commit, branch, checkout, merge, cherry-pick. Tags appear as small badges above commit dots. Commit IDs are optional — useful for labeling key commits in documentation.

gitGraph
    commit id: "Initial commit"
    commit id: "Project setup"

    branch develop
    checkout develop
    commit id: "Add auth module"

    branch feature/payments
    checkout feature/payments
    commit id: "Stripe integration"
    commit id: "Webhook handler"
    commit id: "Tests"

    checkout develop
    merge feature/payments id: "Merge payments"

    checkout main
    merge develop id: "Release v1.0" tag: "v1.0"
    commit id: "Hotfix: typo"
Try in Editor →

Cherry-Pick

Cherry-pick shows a commit copied from one branch to another — common in hotfix workflows:

gitGraph
    commit id: "init"
    branch hotfix
    checkout hotfix
    commit id: "Critical fix" tag: "v1.0.1"
    checkout main
    cherry-pick id: "Critical fix"
    commit id: "Continue main work"
Try in Editor →

Timeline

Timeline diagrams display events on a chronological axis, grouped into time periods. They are ideal for product roadmaps, company history pages, project retrospectives, and release notes summaries.

The syntax is extremely simple: each time period is a label followed by one or more events prefixed with :. Multiple events in the same period just add more : event lines. Unlike Gantt charts, there are no durations or dependencies — timelines are for narrative, not scheduling.

Use timelines when you want to show what happened when, not how long things took.

timeline
    title Product Roadmap 2026
    Q1 2026 : Launch v1.0
            : 1,000 users
    Q2 2026 : Template library
            : VS Code extension
            : 10,000 users
    Q3 2026 : Team collaboration
            : API access (beta)
    Q4 2026 : Enterprise tier
            : SOC 2 certification
Try in Editor →
timeline
    title Mermaid.js History
    2014 : Created by Knut Sveidqvist
         : First public release
    2016 : Version 5 — major rewrite
    2019 : Added to GitHub markdown
    2021 : Class diagram improvements
         : Entity relationship diagrams added
    2022 : Mindmap and timeline support added
    2023 : Block diagram, quadrant chart
         : XY chart (beta)
    2024 : Packet diagram
         : Architecture diagram (beta)
    2025 : Wide enterprise adoption
Try in Editor →

Themes and Configuration

Built-in Themes

%%{init: {'theme': 'default'}}%%
%%{init: {'theme': 'dark'}}%%
%%{init: {'theme': 'forest'}}%%
%%{init: {'theme': 'neutral'}}%%
%%{init: {'theme': 'base'}}%%

The base theme is the most customizable — it accepts themeVariables overrides.

Custom Colors with ThemeVariables

%%{init: {
  'theme': 'base',
  'themeVariables': {
    'primaryColor': '#7c3aed',
    'primaryTextColor': '#ffffff',
    'primaryBorderColor': '#5b21b6',
    'lineColor': '#6b7280',
    'secondaryColor': '#ede9fe',
    'tertiaryColor': '#f3f4f6'
  }
}}%%
flowchart TD
    A[Purple Theme] --> B[Custom Colors]
Try in Editor →

Per-Node Styling

flowchart TD
    A:::highlight --> B:::muted
    classDef highlight fill:#7c3aed,color:white,stroke:#5b21b6
    classDef muted fill:#f3f4f6,color:#6b7280,stroke:#e5e7eb
    style B stroke-width:2px,stroke-dasharray: 5 5
Try in Editor →

Best Practices

Keep diagrams focused. One diagram should answer one question. If a flowchart has more than 20 nodes, split it into multiple diagrams at different abstraction levels — one showing the overall system, one zooming into a subsystem. A 50-node diagram looks thorough and communicates nothing.

Use meaningful node IDs. A --> B --> C creates a maintenance nightmare. Use validate --> auth --> respond — the ID becomes self-documenting and git diffs show what actually changed, not just that "something in the diagram changed."

Match direction to reading pattern. LR (left-right) for pipelines, data flows, and timelines. TD (top-down) for hierarchies, decision trees, and org charts. The direction should match how a reader naturally scans that type of information.

Put diagrams next to the code they document. A ARCHITECTURE.md in the repo root, or inline in a README.md, is infinitely more useful than a diagram in a Confluence page that no one updates. When the code changes, the person making the change is more likely to update a diagram that lives in the same file.

Version control the source, not the image. Committing a PNG or SVG export of a diagram loses the edit history and makes diffs unreadable. Commit the Mermaid source text. Let the platform render it. The only exception is CI-generated diagrams in release artifacts.

Test in the live editor first. Paste new syntax into mermaideditor.lol before committing. The instant preview catches parsing errors immediately — much faster than a commit → CI → render cycle.

Pick the right diagram type. The most common mistake is using a flowchart for everything. If you are modeling states, use a state diagram. If you are modeling data, use an ER diagram. The right diagram type makes the same information 10× clearer.

Keep node labels short. Long labels create large nodes that push other elements around and make the diagram hard to read at a glance. Move detail into a written explanation beside the diagram. The diagram communicates structure; the text communicates nuance.

Where to Use Mermaid.js

GitHub & GitLab — Native support in .md files, issues, pull requests, wikis, and GitHub Pages. Just use a fenced mermaid code block. No plugin or extension required. This alone makes Mermaid the default choice for any team already on GitHub — the diagrams live with the code, render in PRs, and get reviewed like code.

Notion — Paste Mermaid source into a Code block, set the language to "Mermaid", and it renders inline in the page. Works in both page body and database page views.

Obsidian — Mermaid support is bundled by default. Diagrams render in preview mode with no plugin needed. Popular for personal knowledge bases and second-brain workflows.

VS Code — Install "Markdown Preview Mermaid Support" to render diagrams in the markdown preview pane. The "Mermaid Preview" extension adds a dedicated split-pane editor similar to mermaideditor.lol.

Confluence — Install the "Mermaid Diagrams" app from the Atlassian Marketplace. Paid plans only, but widely used in enterprise documentation workflows.

Docusaurus — Add @docusaurus/theme-mermaid and set markdown.mermaidTheme in your config. Official plugin, maintained by Meta.

Nextra / VitePress / Astro — Community plugins available for all three. One config line, then use code blocks normally.

Mermaid CLI — Install @mermaid-js/mermaid-cli globally (npm install -g @mermaid-js/mermaid-cli) and run mmdc -i diagram.mmd -o diagram.svg to render from the command line. Useful in CI pipelines that generate documentation artifacts.

Custom applicationsnpm install mermaid, call mermaid.initialize({startOnLoad: false}), then const { svg } = await mermaid.render('id', diagramText) to get SVG output programmatically. Useful for apps that let users create or preview diagrams.

Practice: Try These Examples Live

The best way to learn Mermaid is to copy these examples into the editor and start changing them. Swap TD to LR, change a solid arrow to dotted, rename nodes, add a subgraph.

Open Mermaid Live Editor →

No sign-up, no install. Instant preview. Export to PNG or SVG when you are done.

For more in-depth coverage of specific diagram types, see:

- Mermaid Flowchart Tutorial

- Mermaid Sequence Diagram Tutorial

- Mermaid Gantt Chart Examples

- Mermaid Syntax Cheat Sheet