🧜♀️ Learning Mermaid: A Complete Tutorial for Diagram Creation
A picture is worth a thousand words, but drawing one in a graphics editor is a thousand clicks. Mermaid flips that: you write a few lines of plain text and it renders a clean diagram for you. Because the source is text, your diagrams live in Git right next to the code they describe — versioned, reviewable, and easy to change. This tutorial walks through every major diagram type, and every example here actually renders.
Reference & Extra Tutorials · Resources · Diagrams as Code
🎯 What This Covers
By the end of this reference, you will be able to:
- Explain what Mermaid is and add it to any HTML page or Markdown doc
- Build flowcharts with the full range of node shapes and directions
- Write sequence diagrams for API and service interactions
- Model object structure with class diagrams and databases with ER diagrams
- Capture system behavior with state diagrams and history with gitGraph
- Avoid the handful of syntax traps that silently break a diagram
Estimated Time: 55 minutes
Practice: Diagram a small app end to end — a flowchart, a sequence diagram, and an ER diagram.
In This Tutorial
What Is Mermaid?
Mermaid is a JavaScript library that turns Markdown-inspired text into diagrams. You describe the nodes (the boxes) and the relationships (the arrows) in a simple syntax, and Mermaid draws and lays them out automatically. It's the same idea as Markdown itself: write plain text, get a formatted result — except the result is a chart instead of a heading.
Think of Mermaid syntax like a recipe. A recipe lists ingredients and how they combine; a Mermaid diagram lists elements and how they connect. The first word — flowchart, sequenceDiagram, erDiagram — is you choosing which dish you're making, and each has its own rules.
Here is the smallest possible flowchart. This one renders:
💡 Why teams love diagrams-as-code
- Version control friendly — the diagram is text, so Git tracks every change and shows clean diffs
- Fast to edit — change a label by editing a word, no design tool needed
- Lives with the code — GitHub, GitLab, and many docs tools render Mermaid inline in Markdown
- Consistent — the layout engine keeps everything aligned automatically
Adding Mermaid to a Page
There are two common ways to get Mermaid running.
Option 1: The CDN (fastest to try)
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true });
</script>
Option 2: NPM (for real applications)
# Install it as a dependency
npm install mermaid
import mermaid from "mermaid";
mermaid.initialize({ startOnLoad: true });
Where the diagram goes
Put your diagram text inside an element with the class mermaid. On page load, Mermaid finds every such element and renders it.
<div class="mermaid">
graph TD
A[Start] --> B[Finish]
</div>
In Markdown files on GitHub or GitLab, you don't need any of the setup — just a fenced code block tagged mermaid:
```mermaid
graph LR
A[Idea] --> B[Diagram]
```
📖 graph vs flowchart
You'll see both graph TD and flowchart TD in the wild. They're aliases for the same diagram; flowchart is the newer keyword. Either works. The letters after it set direction: TD/TB top-to-bottom, BT bottom-to-top, LR left-to-right, RL right-to-left.
Flowcharts
Flowcharts are the workhorse: processes, decision trees, architectures. A flowchart is just nodes joined by arrows.
Node shapes
The brackets around a node's text choose its shape:
flowchart TD
A[Rectangle]
B(Rounded)
C([Stadium])
D[[Subroutine]]
E[(Database)]
F((Circle))
G{Decision}
H{{Hexagon}}
Arrows and labels
flowchart LR
A[Solid arrow] --> B[Node]
C[Dotted] -.-> D[Node]
E[Thick] ==> F[Node]
G[Labeled] -->|yes| H[Node]
Real example: a login flow
Decisions use the diamond shape {...}, and the arrow labels carry the branch conditions.
Grouping with subgraphs
A subgraph draws a labeled box around related nodes — great for showing layers or services.
⚠️ Parentheses in labels must be quoted
If a node label contains parentheses, wrap the whole label in double quotes or the parser chokes. Write A["fs.readFile()"], never A[fs.readFile()]. The same goes for other special characters like colons.
Sequence Diagrams
Sequence diagrams show messages passing between participants over time. They're ideal for API calls and service-to-service communication. Time flows downward; each arrow is a message.
Basic syntax
sequenceDiagram
participant A as Alice
participant B as Bob
A->>B: Hello Bob how are you
B->>A: I am good thanks
A->>B: Great to hear
Real example: API authentication
alt and else draw a labeled box for a branch. Notice the message text is plain prose — that's a hard rule, explained below.
⚠️ Message text must be plain prose
Everything after the colon in a sequence message must avoid ;, parentheses (), ==, and ? — those characters confuse the parser and silently break the render. Write "Recompute the hash and compare", not "SHA256(x) == stored?". Rephrase into words and the diagram renders every time.
💡 The mailroom analogy
A sequence diagram is like tracking letters between mailboxes. Each participant is a mailbox, each arrow is a letter, and reading top to bottom replays the whole conversation in order — perfect for seeing exactly where a message got lost.
Class Diagrams
Class diagrams describe object-oriented structure: classes, their attributes and methods, and how they relate. They're the blueprint before the code.
Basic syntax
classDiagram
class Animal {
+String name
+int age
+makeSound() void
}
class Dog {
+String breed
+fetch() void
}
Animal <|-- Dog
Relationship types
| Notation | Meaning |
|---|---|
<|-- | Inheritance (is a) |
*-- | Composition (owns, dies with) |
o-- | Aggregation (has, outlives) |
--> | Association (uses) |
..> | Dependency |
Real example: an e-commerce model
💡 The blueprint analogy
A class diagram is an architectural blueprint for software. Classes are rooms, attributes are the furniture, methods are what each room does, and the relationship lines are the hallways and doorways connecting them.
State Diagrams
State diagrams model the states a system can be in and the events that move it between them — perfect for order lifecycles, UI flows, and any finite-state machine. Use stateDiagram-v2; [*] marks the start and end.
Basic syntax
stateDiagram-v2
[*] --> Idle
Idle --> Processing: Start task
Processing --> Complete: Task finished
Processing --> Failed: Error thrown
Complete --> [*]
Failed --> Idle: Reset
Real example: an order's lifecycle
💡 The water-phase analogy
Think of water as ice, liquid, or vapor. Each is a state; temperature changes are the events that trigger transitions. A state diagram captures exactly that — the possible states and what pushes the system from one to the next.
ER Diagrams
Entity-relationship diagrams describe a database's structure: the tables (entities), their columns (attributes), and how they relate. They're the plan you draw before writing a single CREATE TABLE.
Basic syntax
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE_ITEM : contains
CUSTOMER {
string name
string email
}
ORDER {
int orderNumber
date orderDate
}
Reading the crow's-foot notation
| Notation | Relationship |
|---|---|
||--|| | one to one |
||--o{ | one to many (zero or more) |
||--|{ | one to many (one or more) |
}o--o{ | many to many |
Real example: a blog database
💡 The family-tree analogy
An ER diagram is a family tree for data. Entities are people, attributes are their traits, and the relationship lines show how they connect — one-to-one for spouses, one-to-many for a parent and their children.
Git Graphs
A gitGraph visualizes branches, commits, and merges — a great way to teach a branching strategy or document a release history.
gitGraph
commit id: "init"
branch feature
checkout feature
commit id: "add form"
commit id: "add tests"
checkout main
merge feature
commit id: "release"
📖 A quick tour of what you've seen
Flowchart, sequence, class, state, ER, and gitGraph cover the vast majority of everyday documentation needs. Mermaid also supports pie charts, Gantt charts, user-journey maps, mindmaps, and timelines — once you're comfortable with the six here, the rest follow the same "declare a type, then describe the parts" pattern.
Rules That Keep Diagrams Rendering
Most "my diagram is blank" problems come from a small set of syntax traps. Internalize these five and your diagrams will render the first time.
1. Quote labels with parentheses or special characters
A["parse(input)"] renders; A[parse(input)] breaks. Wrap any label containing (), :, or other punctuation in double quotes.
2. Never name a node end
Lowercase end is a reserved keyword in flowcharts. A node called end can collapse the whole diagram. Use done, finish, or Endpoint instead.
3. Keep sequence messages as plain prose
After the colon in a sequenceDiagram message, avoid ;, (), ==, and ?. "Validate the token and respond" renders; "validate(token) == ok?" does not.
4. Mind the diagram-type keyword
The first line declares the type: flowchart/graph, sequenceDiagram, classDiagram, stateDiagram-v2, erDiagram, gitGraph. A typo here means nothing renders. Match the syntax to the type you declared.
5. Don't hard-code colors that fight the theme
Avoid style X fill:#f96 and classDef color directives. They look fine in light mode and become unreadable in dark mode. Leave nodes unstyled and let the theme control them — every diagram on this page does exactly that.
When a diagram won't render, paste it into the Mermaid Live Editor. It shows the exact parse error and line number, which turns a mysterious blank box into a one-minute fix.
Practice & Quiz
🏋️ Exercise 1: Fix the broken flowchart
Goal: This flowchart refuses to render. Find and fix the two problems.
flowchart TD
start[Begin] --> load[readFile(config)]
load --> end[Stop]
💡 Hint
One node has an unquoted label with parentheses. Another node uses a reserved keyword for its id.
✅ Solution
flowchart TD
start[Begin] --> load["readFile(config)"]
load --> done[Stop]
Quoting "readFile(config)" fixes the parentheses; renaming end to done frees the reserved word.
🏋️ Exercise 2: Diagram a login sequence
Goal: Write a sequence diagram with three participants (User, Frontend, Backend) showing a successful login and a failed one, using alt/else. Keep all message text as plain prose.
✅ Solution
sequenceDiagram
participant User
participant FE as Frontend
participant BE as Backend
User->>FE: Enter credentials
FE->>BE: Submit login request
alt Credentials are valid
BE->>FE: Return session token
FE->>User: Show dashboard
else Credentials are invalid
BE->>FE: Return an error
FE->>User: Show error message
end
🎯 Quick Quiz
Question 1: Why store diagrams as Mermaid text instead of image files?
Question 2: Which flowchart node label will break the render?
Question 3: What's wrong with this sequence message: A->>B: verify(token) == ok?
Best Practices & Pitfalls
✅ Do
- Keep each diagram focused — split a sprawling one into several smaller views
- Quote any label containing parentheses, colons, or other punctuation
- Use consistent, descriptive node ids and labels
- Store diagrams next to the code they describe so they stay in sync
- Test a tricky diagram in the Mermaid Live Editor before committing
❌ Don't
- Name a flowchart node
end— it's reserved and can blank the diagram - Put
;,(),==, or?in sequence-diagram message text - Hard-code
fill:#hexcolors that become unreadable in dark mode - Cram thirty nodes into one chart — nobody can read it
- Let diagrams rot — update them when the system changes
✅ Living documentation
The whole point of diagrams-as-code is that they can stay true. Put the Mermaid source in the same pull request as the code change it describes, and reviewers will keep both honest together.
Summary
🎉 Key Takeaways
- Mermaid turns plain text into diagrams that live in version control
- The pattern is always the same: declare a type, then describe nodes and relationships
- You now have six workhorses: flowchart, sequence, class, state, ER, and gitGraph
- The render-breaking traps are few: quote parenthesized labels, avoid the
endkeyword, keep sequence messages prose-only, and skip hard-coded colors - When in doubt, the Mermaid Live Editor shows the exact error
📚 Additional Resources
- Mermaid — official documentation
- Mermaid Live Editor — try and debug diagrams
- Mermaid — getting started guide
🚀 What's Next?
You've been rendering diagrams in the browser; next you'll master the environment where you'll run most of your backend tools. Up next: the Ubuntu Command Line Interface — navigating, managing files, permissions, pipes, and enough shell to be dangerous in the best way.
🎉 You speak Mermaid now!
From here on, any system you build can document itself. A few lines of text, and your architecture is a picture your whole team can read.