Markdown Diagrams Tutorial: Drawing Flowcharts, Sequence Diagrams, and Gantt Charts with Mermaid

Wait, Markdown Can Draw Diagrams? A Mermaid Primer

When writing technical docs, you often need diagrams — flowcharts, architecture diagrams, sequence diagrams, that kind of thing. The traditional approach is to fire up draw.io or Visio, create the diagram, export it as an image, and embed it. But this creates a real problem: the diagram lives separately from the text. Update the docs, and you have to go back into the diagramming tool and update the graphic too. Over time, they drift out of sync.

Mermaid solves exactly this problem. It lets you write diagram definitions as plain text right inside your Markdown, and the renderer draws the diagram for you automatically. The code sits alongside your documentation, version control is a breeze, and changing a node is as simple as editing a line of text.

Put simply, Mermaid is a JavaScript-based diagramming library that uses a Markdown-like text syntax to define all sorts of charts and diagrams. GitHub has natively supported Mermaid since 2022, and nowadays tools like Typora, Obsidian, GitLab, and VS Code can all render Mermaid diagrams out of the box.

Basic Syntax: The mermaid Code Block

Using Mermaid in Markdown is straightforward — just write a code block tagged with mermaid:

```mermaid
flowchart TD
    A[Start] --> B{Continue?}
    B -->|Yes| C[Process]
    B -->|No| D[End]
    C --> D

When rendered, this produces a top-to-bottom flowchart with a decision node and two branches. The core workflow is just three steps:

1. Open a code block with ` ```mermaid `
2. Define your diagram using Mermaid syntax inside it
3. Save the file — the renderer generates an SVG chart automatically

One thing worth knowing: Mermaid uses `%%` for comments, similar to the double-slash comments in many programming languages:

```markdown
```mermaid
flowchart TD
    %% This is a comment, it won't appear in the diagram
    A --> B

## Flowcharts — The Most Common Diagram Type

Flowcharts are the most frequently used diagram type in Mermaid. To define one, start with the `flowchart` keyword followed by a direction:

| Direction | Keyword | Description |
|-----------|---------|-------------|
| Top to bottom | `TD` or `TB` | Top-Down / Top-Bottom |
| Bottom to top | `BT` | Bottom-Top |
| Left to right | `LR` | Left-Right |
| Right to left | `RL` | Right-Left |

### Node Shapes

The shape of a node is determined by the symbols wrapping its text — a detail many tutorials gloss over:

```markdown
```mermaid
flowchart LR
    A[Rectangle] --> B(Rounded rectangle)
    B --> C{Diamond decision}
    C --> D[(Database)]
    D --> E[[Subroutine]]
    E --> F>Asymmetric shape]

- `[]` — Standard rectangle
- `()` — Rounded rectangle
- `{}` — Diamond (typically used for decisions)
- `[()]` — Cylinder (database)
- `[[]]` — Subroutine
- `>` — Asymmetric shape

Honestly, the ones you will use most of the time are `[]`, `()`, and `{}`. The rest are there when you need them.

### Connection Lines

There are several ways to write connection lines, each corresponding to a different line style and arrowhead:

```markdown
```mermaid
flowchart LR
    A --> B    %% Solid line with arrow
    C --- D    %% Solid line, no arrow
    E -->|text| F   %% Solid arrow with label
    G -.-> H   %% Dashed line with arrow
    I ==> J    %% Thick line with arrow

| Syntax | Result |
|--------|--------|
| `-->` | Solid line + arrow |
| `---` | Solid line, no arrow |
| `-->\|text\|` | Solid line + arrow + label text |
| `-.->` | Dashed line + arrow |
| `==>` | Thick line + arrow |

### Subgraphs

When a flowchart gets complex, you can use `subgraph` to group related nodes together:

```markdown
```mermaid
flowchart TB
    subgraph Client
        A[Open page] --> B[Fill form]
    end
    subgraph Server
        C[Receive request] --> D[Validate data]
        D --> E[Write to database]
    end
    B --> C
    E --> F[Return result]

My personal rule of thumb: once a flowchart exceeds 8 nodes, I start thinking about using subgraphs to partition it. Otherwise the chart becomes a tangled mess and readability tanks.

### `flowchart` vs `graph` — What's the Difference?

You might come across older articles that use `graph` instead of `flowchart`. That is because early versions of Mermaid only had the `graph` keyword, and `flowchart` was added later as a replacement. The key differences:

- `flowchart` supports more connection line types (like bidirectional arrows `<-->`)
- `flowchart` allows direct connections between subgraphs
- `graph` is the legacy syntax — it still works but is not recommended for new projects

If you are just getting started, go straight for `flowchart`. No need to overthink it.

## Sequence Diagrams — Interaction Flows

Sequence diagrams are great for describing the order of interactions between multiple actors — think request-response flows between a client and server, or the step-by-step operations between a user and a system.

```markdown
```mermaid
sequenceDiagram
    participant User
    participant Frontend
    participant Backend
    participant Database

    User->>Frontend: Enter username and password
    Frontend->>Backend: Send login request
    Backend->>Database: Query user info
    Database-->>Backend: Return user data
    Backend-->>Frontend: Return login result
    Frontend-->>User: Display login success

### Arrow Types in Sequence Diagrams

| Syntax | Meaning |
|--------|---------|
| `->>` | Solid arrow (request) |
| `-->>` | Dashed arrow (response/return) |
| `--)` | Solid open arrow |
| `--)` | Dashed open arrow |
| `-x` | Solid arrow with X (async) |

### Advanced Usage: Loops and Conditionals

You can use keywords like `loop`, `alt`, and `opt` inside sequence diagrams to represent loops and conditional branches:

```markdown
```mermaid
sequenceDiagram
    loop Every 5 seconds
        Client->>Server: Heartbeat check
        Server-->>Client: Confirm alive
    end

    alt Auth succeeded
        Server-->>Client: Return Token
    else Auth failed
        Server-->>Client: Return error
    end

The `note` keyword lets you add annotations in sequence diagrams, positioned above or to the right of a participant:

```markdown
```mermaid
sequenceDiagram
    participant A as Alice
    participant B as Bob
    Note over A,B: This note spans both participants
    A->>B: Hello
    Note right of B: This note appears to the right of Bob

## Gantt Charts — Project Scheduling

Gantt charts are extremely useful for project management and task scheduling. Mermaid's Gantt chart syntax is fairly intuitive:

```markdown
```mermaid
gantt
    title Project Development Plan
    dateFormat YYYY-MM-DD
    axisFormat %m/%d

    section Requirements
    Requirements research       :done, req1, 2024-01-01, 10d
    Requirements review       :active, req2, after req1, 3d

    section Development
    Frontend development       :dev1, after req2, 15d
    Backend development       :dev2, after req2, 12d

    section Testing & Launch
    Integration testing       :test1, after dev1, 7d
    Official launch       :milestone, launch, after test1, 0d

Key syntax points:

- `dateFormat` — Sets the date format
- `section` — Task grouping
- `done` / `active` — Task status (completed / in progress)
- `crit` — Critical task (highlighted in red)
- `milestone` — Milestone (diamond marker)
- `after taskID` — Indicates a task starts after another one finishes

One gotcha I ran into: `dateFormat` must match the actual date format you write. If you set `YYYY-MM-DD` but write a date like `01/15/2024`, the chart will simply fail to render. And the error message is not exactly helpful, so tracking it down can be frustrating.

## Class Diagrams — Code Structure

Class diagrams are ideal for describing class relationships in object-oriented design. If you are writing technical docs for a Java, C#, or TypeScript project, these come in handy.

```markdown
```mermaid
classDiagram
    class Animal {
        +String name
        +int age
        +makeSound() void
    }
    class Dog {
        +String breed
        +fetch() void
    }
    class Cat {
        +bool isIndoor
        +purr() void
    }

    Animal <|-- Dog
    Animal <|-- Cat

How to represent relationships between classes:

| Syntax | Relationship |
|--------|-------------|
| `<\|--` | Inheritance |
| `*--` | Composition |
| `o--` | Aggregation |
| `-->` | Association |
| `--\|>` | Implementation |
| `..>` | Dependency |

Class member access modifiers: `+` is public, `-` is private, `#` is protected.

## State Diagrams

State diagrams describe how an object transitions between different states. They are common in embedded development, game logic, and workflow design.

```markdown
```mermaid
stateDiagram-v2
    [*] --> Draft
    Draft --> UnderReview: Submit application
    UnderReview --> Approved: Review passed
    UnderReview --> Rejected: Review rejected
    Rejected --> Draft: Edit and resubmit
    Approved --> [*]

`[*]` represents the start and end states. `stateDiagram-v2` is the newer keyword, supporting more features than the older `stateDiagram` (such as nested states and notes).

You can also use `note` to add explanatory text to state diagrams:

```markdown
```mermaid
stateDiagram-v2
    state "Loading" as loading
    [*] --> loading
    loading --> Success: Request completed
    loading --> Failed: Request error

    note right of loading
        Display loading animation
        Waiting for server response
    end note

## Pie Charts

Pie charts are the simplest Mermaid diagram type, perfect for showing proportional distributions:

```markdown
```mermaid
pie title Frontend Framework Usage Share
    "React" : 40
    "Vue" : 30
    "Angular" : 15
    "Other" : 15

The syntax is just a few lines: start with the `pie` keyword, write your title after `title`, then add one `"name" : value` pair per line. The value can be a percentage or a raw number — Mermaid calculates the proportions automatically.

## ER Diagrams (Entity-Relationship Diagrams)

ER diagrams describe relationships between entities in a database. If you do backend development or database design, you will reach for these often:

```markdown
```mermaid
erDiagram
    CUSTOMER ||--o{ ORDER : places
    ORDER ||--|{ LINE-ITEM : contains
    CUSTOMER {
        string name
        string email
        int age
    }
    ORDER {
        int id
        string status
        date created_at
    }
    LINE-ITEM {
        string product_name
        int quantity
        float price
    }

Relationship notation:

| Symbol | Meaning |
|--------|---------|
| `\|\|--\|\|` | One-to-one (required) |
| `\|\|--o{` | One-to-many (optional) |
| `\|\|--\|{` | One-to-many (required) |
| `}o--o{` | Many-to-many |

## Which Diagram Should You Use? A Quick Decision Guide

| Scenario | Recommended Diagram | Keyword |
|----------|---------------------|---------|
| Business process / Approval flow | Flowchart | `flowchart` |
| System interaction / API calls | Sequence diagram | `sequenceDiagram` |
| Project scheduling / Task planning | Gantt chart | `gantt` |
| Code architecture / Inheritance | Class diagram | `classDiagram` |
| State machine / Workflow | State diagram | `stateDiagram-v2` |
| Proportional distribution | Pie chart | `pie` |
| Database design | ER diagram | `erDiagram` |

If you are not sure which one to pick, a flowchart covers most scenarios. Sequence diagrams come in second, especially when you are writing web development or microservices documentation.

## Platform Support for Mermaid

How Mermaid renders depends on the tool you are using, and support varies quite a bit across platforms:

| Platform | Support | Notes |
|----------|---------|-------|
| **GitHub** | Native | Auto-renders in README, Issues, and PRs |
| **GitLab** | Native | Similar to GitHub |
| **Typora** | Native | Live preview, best rendering quality |
| **Obsidian** | Native | Make sure Mermaid is enabled in settings |
| **VS Code** | Plugin required | Recommend "Markdown Preview Mermaid Support" extension |
| **Notion** | Limited | Needs to be embedded via a code block |
| **Feishu Docs** | Not supported | Export as image and insert manually |

I have run into this issue in practice: the same Mermaid code rendered fine in Typora, but after pushing to GitHub, a connection line between subgraphs simply vanished. After investigating, it turned out GitHub's Mermaid version was older than Typora's, and some newer syntax was not yet supported. So if your docs will be used across platforms, it is worth previewing on the target platform first.

I recommend using the [Mermaid Live Editor](https://mermaid.live) to test syntax online — write code on the left, see a live preview on the right, and export to SVG or PNG. Very convenient.

## Troubleshooting Common Issues

### Diagram not showing up?

The most common causes:
1. **Wrong code block marker** — Make sure it is ` ```mermaid `, not ` ```markdown ` or ` ```text `
2. **Syntax typos** — Mermaid is case-insensitive for keywords, but any spelling mistake will cause rendering to fail silently
3. **Indentation issues** — While Mermaid is not as indentation-strict as Python, nodes inside a subgraph do need to be aligned

### Special characters rendering incorrectly?

If your node text contains symbols like `()`, `{}`, or `[]`, wrap the text in quotes:

```markdown
```mermaid
flowchart TD
    A["Process data(x, y)"] --> B


### Diagram too large or too small?

Mermaid automatically adjusts the size based on content. If it feels too large, try reducing the number of nodes. If you need precise control over styling, Mermaid supports `classDef` for custom node styles — though that falls into advanced territory.

## References

- [Mermaid Official Docs — Introduction](https://mermaid.js.org/intro/): Mermaid syntax reference and getting started guide
- [GitHub Blog — Include Diagrams in Markdown Files with Mermaid](https://github.blog/developer-skills/github/include-diagrams-markdown-files-mermaid/): GitHub's official Mermaid support announcement
- [GitHub Docs — Creating Diagrams](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-diagrams): Mermaid usage documentation on the GitHub platform