Picking the right tool for creating flowcharts with code sounds simple until you sit down and start writing. Mermaid, Graphviz, and D2 all let you define diagrams as text, but their syntax works in very different ways. Choosing between them affects how fast you can build a diagram, how easy it is to maintain, and how much control you have over the final look. If you're comparing these three tools, you probably want to know exactly how their flowchart syntax differs before committing to one.
What are Mermaid, Graphviz, and D2, and how do they handle flowcharts?
All three are text-based diagramming tools. You write code instead of dragging boxes in a visual editor, and the tool renders the diagram for you. But each takes a different philosophical approach.
Mermaid uses a simplified, almost pseudocode-like syntax designed for Markdown environments. It was built to live inside documentation READMEs, wikis, and note-taking apps. GitHub, GitLab, and Notion all render Mermaid natively. If you've already explored Mermaid flowchart syntax examples for beginners, you know the learning curve is gentle.
Graphviz (specifically the DOT language) has been around since the mid-1990s. It's a mature, layout-engine-driven tool. You describe nodes and edges, and Graphviz's algorithms decide where to place everything. It's powerful but more verbose.
D2 (from Terrastruct) is the newest of the three. It aims to be readable like Mermaid but offer more styling control like Graphviz. Its syntax leans on indentation and a more structured, object-oriented style.
How does the basic flowchart syntax compare across all three?
Here's the same simple flowchart a user login process in each tool's syntax.
Mermaid
Mermaid uses arrow-based connectors with shape brackets to define node appearance:
flowchart TD
A[Start] --> B{Is user logged in?}
B -->|Yes| C[Show Dashboard]
B -->|No| D[Show Login Form]
D --> E[Submit Credentials]
E --> B
Shape types are declared inline: square brackets for rectangles, curly braces for diamonds, parentheses for rounded boxes. This compact format is what makes Mermaid popular in docs and notes. For a deeper dive into a related syntax style, you can also look at how to write flowchart code in PlantUML, which shares some conceptual similarities.
Graphviz (DOT)
Graphviz separates node definitions from edge definitions and uses a more structured graph declaration:
digraph login_flow {
rankdir=TD;
start [label="Start" shape=box];
check [label="Is user logged in?" shape=diamond];
dashboard [label="Show Dashboard" shape=box];
login [label="Show Login Form" shape=box];
submit [label="Submit Credentials" shape=box];
start -> check;
check -> dashboard [label="Yes"];
check -> login [label="No"];
login -> submit;
submit -> check;
}
You define every node with its properties first, then draw edges between them. This is more explicit but requires more lines for a simple diagram.
D2
D2 uses indentation and a colon-based label syntax:
direction: down
start: Start
check: Is user logged in? {
shape: diamond
}
dashboard: Show Dashboard
login: Show Login Form
submit: Submit Credentials
start -> check
check -> dashboard: Yes
check -> login: No
login -> submit
submit -> check
D2 automatically infers shapes based on label content and connections in many cases, but you can override them explicitly. The indentation-based block structure makes it feel more like writing configuration than code.
Which tool has the easiest syntax to learn?
Mermaid wins on simplicity. Its arrow syntax (-->) is intuitive, and you can write a working flowchart in a single sitting without reading docs. The inline shape declarations mean everything about a node lives on one line.
D2 comes second. If you're comfortable with YAML or TOML, the structure feels familiar. It requires less boilerplate than Graphviz and has sensible defaults.
Graphviz has the steepest learning curve. You need to understand the digraph declaration, node attribute syntax, and edge syntax separately. But once you learn it, the mental model is consistent and predictable.
When should you pick Mermaid over Graphviz or D2?
Use Mermaid when:
- You need diagrams embedded in Markdown files, wikis, or docs that support live rendering
- Team members are not diagramming specialists and need to edit flowcharts without training
- Speed matters more than pixel-perfect layout control
- You want something that works directly on GitHub or GitLab without extra tooling
Use Graphviz when:
- You need complex, large-scale diagrams with many nodes and edges
- Automatic graph layout is important (Graphviz's layout algorithms like
dot,neato, andfdpare industry-leading) - You're generating diagrams programmatically from data or code
- You need fine-grained control over every visual attribute
Use D2 when:
- You want a modern syntax that balances readability with styling options
- You need features like automatic layout with more visual polish than Graphviz defaults
- Your team likes structured, indentation-based config formats
- You want a tool that's actively evolving with modern developer workflows in mind
How do the syntax features differ for common flowchart needs?
Subgraphs and grouping
All three support subgraphs (grouping related nodes), but the syntax varies:
- Mermaid: Uses
subgraph name ... endblocks - Graphviz: Uses
subgraph cluster_name { ... }with thecluster_prefix for visual grouping - D2: Uses nested blocks with curly braces nodes defined inside a parent key become part of that group
Edge labels
- Mermaid:
A -->|Label text| BorA -- Label text --> B - Graphviz:
A -> B [label="Label text"] - D2:
A -> B: Label text
D2's approach is the most concise here. Graphviz is the most explicit. Mermaid falls in between.
Shape customization
- Mermaid: Shapes are defined by bracket style
[]for rectangle,{}for diamond,(())for circle,[/ /]for parallelogram. Limited inline styling options. - Graphvirt: Full attribute control
shape,style,fillcolor,fontname, and dozens more on every node and edge. - D2: Supports
shape,style,fill,stroke,font, and more within the block structure. Also supports themes and near-global styling.
Direction control
Mermaid uses flowchart TD (top-down), LR (left-right), etc. at the top of the diagram. Graphviz uses rankdir=LR as a graph attribute. D2 uses direction: right or direction: down.
What are common mistakes when switching between these tools?
Trying to copy syntax directly. The biggest error is assuming syntax from one tool will work in another. Arrow styles, shape declarations, and edge label positions all differ. Even something as small as --> in Mermaid vs -> in Graphviz will break your diagram.
Forgetting that Graphviz uses semicolons. If you come from Mermaid or D2, you'll forget the trailing semicolons in DOT syntax. Every statement in Graphviz needs one.
Assuming the same layout behavior. Mermaid and D2 both make layout decisions based on the order you write things. Graphviz's layout engine does its own thing based on graph topology, not source order. If you switch to Graphviz expecting the same visual output, you'll be surprised.
Overcomplicating Mermaid diagrams. Mermaid handles medium-complexity flowcharts well, but once you push past 20–30 nodes, the rendering gets messy. At that point, Graphviz or D2 with explicit layout hints will serve you better.
Ignoring D2's nesting rules. In D2, indentation creates parent-child relationships. If you accidentally indent a node under another, it becomes a child of that node instead of a sibling. This is a frequent source of broken diagrams for new D2 users.
How do these tools compare for real documentation workflows?
If your team writes docs in Markdown and pushes to Git, Mermaid is the path of least resistance. It renders in pull requests on GitHub and in many static site generators without any build step.
If you need diagrams exported as SVG or PNG for presentations or print, all three support it, but Graphviz has the most mature export pipeline. Tools like Graphviz's official documentation cover every export option in detail.
D2's CLI tool exports to SVG and PNG easily, and it also offers a watch mode for live previewing during editing a nice developer experience that Graphviz doesn't offer natively.
Quick syntax reference comparison
| Feature | Mermaid | Graphviz | D2 |
|---|---|---|---|
| Node definition | Inline with brackets | Separate attribute block | Indented key-value |
| Edge syntax | --> with optional |label| |
-> with [label=""] |
-> with : label |
| Subgraphs | subgraph ... end |
subgraph cluster_ { } |
Nested curly braces |
| Shapes | Bracket style | shape= attribute |
shape: property |
| Themes/styling | Limited built-in themes | Full manual control | Built-in themes + manual |
| Learning curve | Low | Medium-high | Low-medium |
| Platform support | GitHub, GitLab, Notion, many others | CLI, libraries in most languages | CLI, growing integrations |
Practical checklist: choosing the right flowchart syntax for your project
- Where will the diagram live? If it's in Markdown docs on GitHub, start with Mermaid. If it's in a build pipeline or standalone file, all three work.
- How complex is your diagram? Under 20 nodes Mermaid or D2 will be fine. Over 30 nodes with complex relationships Graphviz handles scale better.
- Who edits the diagrams? Non-developers or mixed teams Mermaid. Developers comfortable with config syntax D2. Engineers who need full control Graphviz.
- Do you need advanced styling? Graphviz and D2 both offer more visual control than Mermaid. D2 has built-in themes for quick polish.
- Start small. Write the same 5-node flowchart in all three tools. The one that feels most natural to you is probably the right pick for your workflow.
Flowchart Code Syntax Reference Guide
Diagram as Code Flowchart Markup Cheat Sheet and Syntax Reference
How to Write Flowchart Code in Plantuml
Mermaid Flowchart Syntax Examples for Beginners – Easy Guide & Code Samples
Best Architecture Diagram Tools for Developers: a Comparison Guide
How to Generate Architecture Diagrams From Code