Free · No sign-up · Works with .mmd files

Mermaid flowchart editor

A flowchart shows how control moves through a process: steps, branches, and where the branches rejoin. Reach for one when the interesting part is the order of decisions — a deployment pipeline, a request path, an approval route. If the interesting part is who talks to whom over time, you want a sequence diagram instead.

A CI pipeline with two failure paths

This is the shape most flowcharts on this site start as: a linear happy path with decision nodes that break out of it. Note the quoted label on the last node — brackets inside a label need quoting, which is the single most common flowchart error.

flowchart TD
    Push[Push to main] --> Lint[Lint and typecheck]
    Lint --> Test{Tests pass?}
    Test -->|no| Fail[Notify author on Slack]
    Test -->|yes| Build[Build container image]
    Build --> Scan{CVE scan clean?}
    Scan -->|no| Block["Block release (needs triage)"]
    Scan -->|yes| Deploy[Deploy to production]
    Deploy --> Smoke[Run smoke tests]
    Smoke --> Done[Release complete]
Open this in the editor
Advertisement

Worked examples

1. The minimum useful flowchart

Two nodes and an arrow. `TD` means top-down; `LR` gives you left-to-right, which is usually better for anything wider than it is tall.

flowchart TD
    Request[Incoming request] --> Response[Response sent]
Open in the editor

2. A decision with labelled branches

Curly braces make a diamond. The text between pipes labels the edge, not the node — that distinction matters when you hit the errors section below.

flowchart TD
    Start[Request received] --> Auth{Valid token?}
    Auth -->|yes| Handler[Run handler]
    Auth -->|no| Reject[Return 401]
    Handler --> Done[Return 200]
Open in the editor

3. Node shapes that carry meaning

Shape is the cheapest way to add information to a flowchart. Rounded for start and end, diamond for a decision, cylinder for storage, and the doubled shape for a terminal state.

flowchart LR
    Start([Job scheduled]) --> Read[(Read from Postgres)]
    Read --> Check{Rows to process?}
    Check -->|none| Stop([Exit 0])
    Check -->|some| Work[/Transform rows/]
    Work --> Write[(Write to S3)]
    Write --> Stop
Open in the editor

4. Subgraphs for grouping by owner

Subgraphs draw a box around related nodes. The most useful thing to group by is not process stage but ownership — which team or service is responsible for which part, so the handoffs become visible.

flowchart TD
    subgraph client [Browser]
        UI[User submits form]
    end
    subgraph api [Order service]
        Validate[Validate payload]
        Persist[Write order row]
    end
    subgraph async [Background workers]
        Email[Send confirmation]
        Invoice[Generate invoice]
    end
    UI --> Validate
    Validate --> Persist
    Persist --> Email
    Persist --> Invoice
Open in the editor

5. A retry loop with a bounded exit

Flowcharts handle cycles fine, and a retry loop is where they earn their keep — the diagram makes it obvious whether the loop has an exit. Note `Retry` counts as an ordinary node; only lowercase `end` is reserved.

flowchart TD
    Send[Send webhook] --> Result{2xx response?}
    Result -->|yes| Ack[Mark delivered]
    Result -->|no| Count{Attempt < 5?}
    Count -->|yes| Wait[Back off exponentially]
    Wait --> Send
    Count -->|no| Dead[Move to dead letter queue]
Open in the editor

Flowchart syntax reference

Everything below is flowchart-only syntax. Arrow forms in particular do not carry over to other diagram types — a sequence diagram's `->>` is a parse error here.

SyntaxMeaning
flowchart TDTop-down. Also TB. The default reading order for a process.
flowchart LRLeft-to-right. Also RL. Better for wide, shallow flows.
A[Text]Rectangle — an ordinary step.
A(Text)Rounded rectangle.
A([Text])Stadium shape — conventionally a start or end point.
A[(Text)]Cylinder — a datastore.
A{Text}Diamond — a decision.
A[/Text/]Parallelogram — input or output.
A --> BArrow.
A --- BLine with no arrowhead.
A -.-> BDotted arrow — conventionally async or optional.
A ==> BThick arrow — conventionally the primary path.
A -->|label| BLabelled edge. Quote the label if it contains brackets.
A["Text (with brackets)"]Quoted label — required for brackets, quotes, or anything the parser would read as shape syntax.
subgraph name [Title] ... endGroup nodes in a labelled box. `end` closes it.
%% commentComment line, not rendered.
Advertisement

Six errors that actually break flowcharts

Each of these was reproduced against the renderer this site runs (Mermaid 11.12.2). Paste the broken version into the editor and you will get exactly the error described; the fixed version renders. The fastest way to read a Mermaid parse error is to look at the very end of the message, where it names the token it choked on.

What you see

Parse error, ending in: got 'PS'

Why

An opening parenthesis inside a square-bracket label. Parentheses are shape syntax — `A(text)` is a rounded node — so a bare `(` inside `[...]` is read as the start of a shape.

Fix

Wrap the whole label in double quotes. Anything inside quotes is treated as literal text.

Broken
flowchart TD
    A[Retry (max 5)] --> B[Done]
Fixed
flowchart TD
    A["Retry (max 5)"] --> B[Done]

What you see

Parse error, ending in: got 'STR'

Why

A double quote inside a label. The parser treats it as the start of a quoted string and then hits the closing bracket where it expected the matching quote.

Fix

Use single quotes inside a double-quoted label, or write the character as the entity `#quot;`.

Broken
flowchart TD
    A[Status is "pending"] --> B[Done]
Fixed
flowchart TD
    A["Status is 'pending'"] --> B[Done]

What you see

Parse error, ending in: got 'end'

Why

`end` used as a node id. Lowercase `end` closes a subgraph, so the parser sees a block terminator where a node should be. This one is common precisely because `end` is the natural name for a final node.

Fix

Capitalise it, or give the node an id and put the word in the label.

Broken
flowchart TD
    Start[Begin] --> end
Fixed
flowchart TD
    Start[Begin] --> End[Finished]

What you see

Parse error on the line where you named a node

Why

A space in the node id. The id is the token before the arrow, and a space terminates it, leaving a second bare word the parser cannot place.

Fix

Use a single-word id and put the readable text in the label.

Broken
flowchart TD
    auth service --> user database
Fixed
flowchart TD
    auth[Auth service] --> db[(User database)]

What you see

Parse error on an edge label between pipes

Why

Brackets inside an edge label. `|...|` has the same restriction as a node label — parentheses there are still shape syntax.

Fix

Quote the edge label as well.

Broken
flowchart TD
    A -->|retry (once)| B
Fixed
flowchart TD
    A -->|"retry (once)"| B

What you see

Lexical error on line 1. Unrecognized text.

Why

An invalid direction. Flowcharts accept TB, TD, BT, LR and RL and nothing else, and an unknown one fails in the lexer before any node is read — which is why the error points at line 1 rather than at your mistake.

Fix

Use one of the five. TD and LR cover nearly everything.

Broken
flowchart TOPDOWN
    A --> B
Fixed
flowchart TD
    A --> B

Rendering notes

Measured against Mermaid 11.12.2 as this site runs it, rather than taken from the documentation. These are the behaviours that matter once a flowchart stops being a toy.

Height grows about 105px per node; width barely moves

A top-down flowchart of 3 nodes renders to a viewBox of roughly 122×382. At 40 nodes it is 131×4230 — the width grew by nine pixels and the height by a factor of eleven. Long flowcharts become tall ribbons that no longer fit any screen, which is what the centre button in the preview is for. If a diagram is getting away from you vertically, switching to `flowchart LR` costs one word and often halves the aspect ratio.

Labels are HTML, and that used to break PNG export

Flowchart labels are drawn inside an SVG `<foreignObject>` containing real HTML. That is why `<br>` and basic markdown work inside a label. It also means the browser refuses to rasterise the SVG onto a canvas, which for a long time made PNG export on this site silently hand back an SVG file instead. Export now re-renders the diagram with plain SVG text labels, so PNG works — at the cost of very slightly different label typography in the PNG compared to the screen.

Theme changes colour, never layout

Rendering the same flowchart with the default and dark themes produces a byte-identical viewBox. Switching theme cannot reflow a diagram or push a label out of its box, so if something looks wrong in dark mode it will look equally wrong in light mode.

The exported image is sized from the viewBox, not the screen

Mermaid emits `width="100%"` and no height attribute, so the on-screen size depends on the container. Export reads the viewBox instead and renders at two to three times that, which is why a PNG of a tall flowchart comes out far larger than what you were looking at. Zoom level does not affect the export.

Only lowercase `end` is reserved

`End`, `END` and `ending` are all ordinary node ids. This is worth knowing because the obvious workaround — renaming the node — is usually unnecessary; changing one letter's case is enough.

When to use something else

If the diagram is mostly about who sends what to whom, and the order in time matters more than the branching, a sequence diagram will be clearer and will stay clearer as it grows. A flowchart with six participants encoded as node names is a sequence diagram that has not admitted it yet.

If you are describing the states an object can be in rather than the steps a process goes through, use a state diagram. The test is simple: if your node labels are nouns with adjectives ("order pending", "order shipped") it is a state machine; if they are verbs ("validate payload", "send email") it is a flowchart.

And if the flowchart is over about forty nodes, the honest answer is that no diagram type will save it. Split it into several diagrams with one shared entry point, or accept that the thing you are describing is too complicated to be understood in one picture — which is itself useful information.

Other diagram types

Written by Dominik Malsch · Last updated:

Open the editor →