Why Mermaid Won

In 2022, GitHub added native Mermaid rendering to Markdown files, READMEs, and GitHub Discussions. This single decision changed the landscape: Mermaid diagrams now render where developers already work, without installing anything or buying a tool. GitLab followed, then Notion, then VS Code. Mermaid is now the de facto standard for text-based diagramming in software teams.

Where Mermaid Renders Natively (2026)
  • GitHub — README.md, Issues, Pull Requests, Discussions, GitHub Pages
  • GitLab — all Markdown contexts including wikis
  • Notion — code blocks with mermaid language
  • VS Code — with Markdown Preview Mermaid Support extension
  • Docusaurus, MkDocs, Hugo, Jekyll — via plugins
  • Confluence — via Mermaid for Confluence marketplace app

Flowcharts: Advanced Syntax

You probably know basic flowchart syntax. Here are the advanced features most developers miss:

flowchart TD
    %% Subgraphs group related nodes
    subgraph Client["Client Layer"]
        UI([Web Browser])
        Mobile([Mobile App])
    end

    subgraph API["API Layer"]
        GW[API Gateway]
        Auth[Auth Service]
        Core[Core Service]
    end

    subgraph Data["Data Layer"]
        PG[(PostgreSQL)]
        Redis[(Redis Cache)]
        S3[(S3 Bucket)]
    end

    UI & Mobile --> GW
    GW -->|JWT required| Auth
    GW --> Core
    Core --> PG
    Core --> Redis
    Core --> S3

    %% Style individual nodes
    style Auth fill:#fef3c7,stroke:#d97706
    style PG fill:#dbeafe,stroke:#3b82f6

Key advanced features: subgraph groups nodes visually. %% is a comment. & connects multiple sources to one target. style applies CSS to individual nodes. ([text]) creates a stadium shape, [(text)] creates a cylinder (for databases).

Sequence Diagrams: Every Feature

sequenceDiagram
    autonumber
    actor U as User
    participant B as Browser
    participant GW as Gateway
    participant AS as Auth Service
    participant DB as Postgres

    U->>B: submits login form
    B->>+GW: POST /auth/login {email, password}
    GW->>+AS: validateCredentials(email, pwd)
    AS->>+DB: SELECT * FROM users WHERE email=?
    DB-->>-AS: user row OR null

    alt user not found OR wrong password
        AS-->>GW: 401 Unauthorized
        GW-->>B: 401 { error: "invalid_credentials" }
        B-->>U: show error message
    else success
        AS->>AS: sign JWT (sub, tier, exp)
        AS-->>-GW: 200 { access_token, refresh_token }
        GW-->>-B: 200 { access_token, refresh_token }
        B->>B: store refresh_token in localStorage
        B-->>U: redirect to dashboard
    end

    Note over AS,DB: Passwords are bcrypt-hashed — never stored in plaintext

Key features used: autonumber adds step numbers. actor vs participant changes the shape. +/- on arrows shows activation boxes. alt/else/end creates conditional blocks. Note over adds annotation spanning multiple participants.

Class Diagrams: When You Need Them

Class diagrams are most useful for documenting public APIs, interface contracts, and inheritance hierarchies — not for mapping internal implementation details. Focus on what other developers need to use the code, not how it works internally.

classDiagram
    class UserService {
        +createUser(email, password) User
        +getUserById(id) User
        +updateProfile(id, updates) User
        +deleteUser(id) void
    }

    class User {
        +String id
        +String email
        +String displayName
        +String tier
        +Timestamp createdAt
    }

    class AuthToken {
        +String accessToken
        +String refreshToken
        +int expiresIn
    }

    class Subscription {
        +String id
        +String userId
        +String status
        +Timestamp renewsAt
    }

    UserService --> User : creates/updates
    User "1" --> "0..1" Subscription : has
    UserService ..> AuthToken : returns on login

Entity-Relationship Diagrams

erDiagram
    PRODUCT {
        uuid id PK
        string sku UK
        string name
        decimal price
        int stock_qty
        uuid category_id FK
    }
    CATEGORY {
        uuid id PK
        string name
        string slug UK
    }
    ORDER {
        uuid id PK
        uuid user_id FK
        string status
        decimal total
        timestamp placed_at
    }
    ORDER_LINE {
        uuid id PK
        uuid order_id FK
        uuid product_id FK
        int quantity
        decimal unit_price
    }

    CATEGORY ||--o{ PRODUCT : "contains"
    ORDER ||--|{ ORDER_LINE : "has"
    PRODUCT ||--o{ ORDER_LINE : "referenced by"

Cardinality syntax: ||--|| = one-to-one, ||--o{ = one-to-many (zero allowed), ||--|{ = one-to-many (at least one required), }o--o{ = many-to-many.

State Diagrams: Model Complex Lifecycles

stateDiagram-v2
    [*] --> Pending : order placed

    Pending --> Processing : payment confirmed
    Pending --> Cancelled : payment failed / user cancels

    Processing --> Shipped : warehouse dispatches
    Processing --> Cancelled : stock unavailable

    Shipped --> Delivered : carrier confirms delivery
    Shipped --> ReturnRequested : user requests return

    ReturnRequested --> Refunded : return received
    ReturnRequested --> Rejected : return policy violation

    Delivered --> ReturnRequested : within 30-day window
    Delivered --> [*] : 30-day window closed

    Cancelled --> [*]
    Refunded --> [*]
    Rejected --> [*]

    note right of Processing : Triggers warehouse notification
    note right of Shipped : Sends tracking email

C4 Diagrams Inside Mermaid

Mermaid's C4Context diagram type implements the C4 model directly. This is the cleanest way to keep C4 diagrams in your repo without needing Structurizr:

C4Context
    title System Context — E-Commerce Platform

    Person(customer, "Customer", "Browses and purchases products")
    Person(admin, "Admin", "Manages products and orders")

    System(ecom, "E-Commerce Platform", "Handles product catalog, orders, payments")

    System_Ext(stripe, "Stripe", "Payment processing")
    System_Ext(email, "SendGrid", "Transactional email")
    System_Ext(shipping, "FedEx API", "Shipping rates and tracking")

    Rel(customer, ecom, "Browses, purchases, tracks orders", "HTTPS")
    Rel(admin, ecom, "Manages catalog and fulfillment", "HTTPS")
    Rel(ecom, stripe, "Processes payments", "HTTPS/API")
    Rel(ecom, email, "Sends order confirmations", "HTTPS/API")
    Rel(ecom, shipping, "Fetches rates, creates shipments", "HTTPS/API")

Theming for Dark Mode

Control Mermaid's theme with a %%{init:...}%% directive at the top of the diagram:

%%{init: {'theme': 'dark', 'themeVariables': {
  'primaryColor': '#1e3a5f',
  'primaryTextColor': '#e2e8f0',
  'primaryBorderColor': '#3b82f6',
  'lineColor': '#64748b',
  'secondaryColor': '#0f2037',
  'tertiaryColor': '#0a1628'
}}}%%
flowchart LR
    A[Service A] -->|gRPC| B[Service B]
    B -->|Kafka| C[Event Bus]
    C -->|consume| D[Worker]

Available themes: default, dark, forest, neutral, base. Use base + themeVariables for full custom control.

CI/CD Integration: Generate Diagrams Automatically

Generate PNG/SVG exports in your CI pipeline using the Mermaid CLI (@mermaid-js/mermaid-cli):

# Install
npm install -g @mermaid-js/mermaid-cli

# Convert a .mmd file to SVG
mmdc -i architecture.mmd -o architecture.svg -t dark

# GitHub Actions step
- name: Generate diagrams
  run: |
    npm install -g @mermaid-js/mermaid-cli
    find docs -name "*.mmd" -exec mmdc -i {} -o {}.svg \;
    git add docs/**/*.svg
    git commit -m "chore: regenerate architecture diagrams" || true

This pattern stores .mmd source files as the source of truth and auto-generates SVGs for embedding in HTML documentation sites that can't render Mermaid natively.

Gantt Charts for Project Planning

gantt
    title Q3 2026 — Platform Migration
    dateFormat  YYYY-MM-DD
    axisFormat  %b %d

    section Infrastructure
    Provision new cluster        :done,    infra1, 2026-07-01, 5d
    Configure networking         :done,    infra2, after infra1, 3d
    Set up monitoring            :active,  infra3, after infra2, 4d

    section Migration
    Migrate user service         :         mig1, 2026-07-15, 7d
    Migrate order service        :         mig2, after mig1, 7d
    Migrate payment service      :crit,    mig3, after mig2, 10d

    section Validation
    Load testing                 :         val1, after mig1, 5d
    Security audit               :crit,    val2, after mig3, 7d
    Go-live                      :milestone, 2026-08-20, 0d