How to Create a Flowchart with Mermaid.js — Complete Guide

Step-by-step guide to creating flowcharts with Mermaid.js. Learn node shapes, edge types, styling, subgraphs, and best practices with copy-paste examples.

Introduction to Mermaid Flowcharts

Flowcharts are the most popular diagram type in Mermaid.js, and for good reason. They're versatile enough to represent everything from simple processes to complex decision trees, and Mermaid makes them incredibly easy to create with just a few lines of text.

In this guide, you'll learn every aspect of Mermaid flowcharts — from basic syntax to advanced features like subgraphs, styling, and interaction.

Basic Flowchart Syntax

Every Mermaid flowchart starts with a direction declaration:

graph TD
    A[Start] --> B[Process]
    B --> C[End]
Try in Editor →

The direction keyword controls layout:

  • TD or TB — Top to Bottom (default, most common)
  • LR — Left to Right (great for pipelines)
  • BT — Bottom to Top
  • RL — Right to Left

You can also use flowchart instead of graph for the newer syntax with more features:

flowchart LR
    A[Start] --> B[Process] --> C[End]
Try in Editor →

Node Shapes

Mermaid provides many node shapes to convey meaning visually:

flowchart TD
    A[Rectangle - Default]
    B(Rounded Rectangle)
    C([Stadium Shape])
    D[[Subroutine]]
    E[(Database / Cylinder)]
    F((Circle))
    G{Diamond / Decision}
    H{{"Hexagon"}}
    I>Asymmetric / Flag]
    J[/Parallelogram/]
    K[\Parallelogram Alt\]
    L[/Trapezoid\]
    M[\Trapezoid Alt/]
Try in Editor →

When to Use Each Shape

  • Rectangle ([text]): Standard process steps
  • Rounded ((text)): Start/end terminals
  • Diamond ({text}): Decision points (yes/no, true/false)
  • Cylinder ([(text)]): Databases or storage
  • Circle (((text))): Connectors or junction points
  • Stadium (([text])): Terminal events
  • Parallelogram ([/text/]): Input/output operations

Edge Types — Connecting Nodes

Edges (arrows and lines) are how you connect nodes. Mermaid offers many styles:

flowchart LR
    A -->|Arrow| B
    C ---|Line| D
    E -.->|Dotted arrow| F
    G ==>|Thick arrow| H
    I --o|Circle end| J
    K --x|Cross end| L
Try in Editor →

Edge Length

You can control edge length by adding extra dashes:

flowchart TD
    A --> B
    A ----> C
    A -------> D
Try in Editor →

Longer edges push nodes further apart, which helps with layout.

Labeled Edges

Add labels to describe the relationship:

flowchart TD
    A{Is it raining?}
    A -->|Yes| B[Take umbrella]
    A -->|No| C[Enjoy the sun]
Try in Editor →

You can also use this syntax: A -- "label text" --> B

Practical Example: CI/CD Pipeline

Let's build a real-world flowchart — a CI/CD deployment pipeline:

flowchart LR
    A([Developer pushes code]) --> B[Run Linter]
    B --> C[Run Unit Tests]
    C --> D{Tests pass?}
    D -->|Yes| E[Build Docker Image]
    D -->|No| F[Notify Developer]
    F --> A
    E --> G[Push to Registry]
    G --> H{Environment?}
    H -->|Staging| I[Deploy to Staging]
    H -->|Production| J[Manual Approval]
    J --> K[Deploy to Production]
    I --> L[Run E2E Tests]
    L --> M{E2E pass?}
    M -->|Yes| J
    M -->|No| F
Try in Editor →

This single text block produces a complete CI/CD visualization that's easy to update when the process changes.

Subgraphs — Grouping Related Nodes

Subgraphs let you group nodes into labeled sections:

flowchart TB
    subgraph Frontend
        A[React App] --> B[API Client]
    end
    subgraph Backend
        C[Express Server] --> D[Business Logic]
        D --> E[(PostgreSQL)]
    end
    B --> C
Try in Editor →

Nested Subgraphs

You can nest subgraphs for complex architectures:

flowchart TB
    subgraph Cloud["AWS Cloud"]
        subgraph VPC["VPC"]
            subgraph Public["Public Subnet"]
                ALB[Load Balancer]
            end
            subgraph Private["Private Subnet"]
                ECS[ECS Service]
                RDS[(RDS Database)]
            end
        end
    end
    User([User]) --> ALB --> ECS --> RDS
Try in Editor →

Subgraph Direction

Each subgraph can have its own direction:

flowchart LR
    subgraph TOP
        direction TB
        A --> B
    end
    subgraph BOTTOM
        direction TB
        C --> D
    end
    TOP --> BOTTOM
Try in Editor →

Styling Your Flowcharts

Inline Styles

Apply CSS-like styles directly to nodes:

flowchart LR
    A[Critical]:::critical --> B[Normal] --> C[Success]:::success

    classDef critical fill:#ff6b6b,stroke:#c0392b,color:white
    classDef success fill:#51cf66,stroke:#2f9e44,color:white
Try in Editor →

Style by Node ID

flowchart TD
    A[Important Node]
    style A fill:#f9f,stroke:#333,stroke-width:4px
Try in Editor →

Common Style Patterns

Here's a reusable set of class definitions:

flowchart TD
    A[Start]:::start --> B[Process]:::process --> C{Decision}:::decision
    C -->|Yes| D[Success]:::success
    C -->|No| E[Error]:::error

    classDef start fill:#667eea,stroke:#5a67d8,color:white
    classDef process fill:#f7fafc,stroke:#cbd5e0
    classDef decision fill:#faf089,stroke:#d69e2e
    classDef success fill:#c6f6d5,stroke:#38a169
    classDef error fill:#fed7d7,stroke:#e53e3e
Try in Editor →

Advanced Techniques

Multiple Links from One Node

flowchart TD
    A[Router] --> B[Handler 1]
    A --> C[Handler 2]
    A --> D[Handler 3]
    B & C & D --> E[Response]
Try in Editor →

The & operator connects multiple nodes at once.

Special Characters in Labels

Use quotes for special characters:

flowchart LR
    A["Node with (parentheses)"] --> B["Contains {braces}"]
    B --> C["Has #quot;quotes#quot;"]
Try in Editor →

Comments

Add comments with %%:

flowchart TD
    %% This is a comment
    A --> B
    %% Another comment
    B --> C
Try in Editor →

Best Practices for Flowcharts

  1. Choose direction wisely. Use LR for processes/pipelines, TD for hierarchies and decision trees.
  1. Use meaningful node IDs. Instead of A, B, C, try start, validate, deploy. It makes the source readable.
  1. Label your edges. Decision diamonds should always have labeled outputs (Yes/No, True/False, Success/Error).
  1. Keep it focused. A flowchart with more than 15-20 nodes becomes hard to read. Split complex flows into multiple diagrams.
  1. Use subgraphs for logical grouping. They make large diagrams scannable.
  1. Apply consistent styling. Define class definitions once and reuse them. Color-code by category (errors = red, success = green, etc.).
  1. Test incrementally. Build your flowchart step by step, rendering after each addition. This makes it easy to catch syntax errors.

Common Mistakes and Fixes

Problem: Nodes not connecting properly.

Fix: Make sure node IDs are consistent. A and a are different nodes.

Problem: Text with special characters breaks rendering.

Fix: Wrap text in double quotes: A["My (special) text"]

Problem: Layout is messy with too many crossing lines.

Fix: Rearrange node order in the source. Mermaid renders top-to-bottom in the order nodes appear. Also try changing direction (LR vs TD).

Problem: Subgraph edges look wrong.

Fix: Connect to specific nodes inside subgraphs, not the subgraph itself.

Conclusion

Mermaid flowcharts are powerful enough for real-world documentation yet simple enough to create in seconds. Start with basic nodes and arrows, then progressively add shapes, styles, and subgraphs as needed. The key advantage is maintainability — when your process changes, updating a few lines of text is infinitely easier than rearranging boxes in a drawing tool.

Try it now in our free Mermaid Live Editor →