Mermaid guide

Mermaid State Diagram Syntax: States, Transitions, Composite States, and Forks

A state diagram models something that is always in exactly one state and moves between states on events. Mermaid's stateDiagram-v2 renders states as rounded boxes and transitions as labelled arrows, with [*] for the start and end pseudo-states.

It is the best way to document an order lifecycle, a connection handshake, a UI component with modes, or any workflow engine configuration. Compared with a flowchart, the semantics are stricter: arrows mean "on this event, move here", not "then do this".

  • lifecycle modelling
  • workflow engines
  • protocol state machines
  • UI state transitions

Example

Mermaid State Diagram example

user types

debounce 300ms

success

parse fail

user fixes

click Share

API ok

Idle

Editing

Rendering

Rendered

Error

Sharing

Shared

stateDiagram-v2
    [*] --> Idle
    Idle --> Editing : user types
    Editing --> Rendering : debounce 300ms
    Rendering --> Rendered : success
    Rendering --> Error : parse fail
    Error --> Editing : user fixes
    Rendered --> Sharing : click Share
    Sharing --> Shared : API ok
    Shared --> [*]

Syntax

States and transitions

stateDiagram-v2
    [*] --> Draft
    Draft --> Review : submit
    Review --> Draft : request changes
    Review --> Published : approve
    Published --> [*]
States and transitions — Mermaid state

submit

request changes

approve

Draft

Review

Published

Transition text after the colon is the event or guard. State names with spaces need an alias: state "In Review" as Review.

Try this snippet →

Composite states

stateDiagram-v2
    [*] --> Active
    state Active {
        [*] --> Idle
        Idle --> Running : start
        Running --> Idle : stop
    }
    Active --> Stopped : shutdown
Composite states — Mermaid state

shutdown

Active

start

stop

Idle

Running

Stopped

A composite state has its own start marker and internal transitions. Nest as deep as needed.

Try this snippet →

Choice, fork, and join

stateDiagram-v2
    state check <<choice>>
    state fork <<fork>>
    state join <<join>>
    [*] --> check
    check --> Small : size < 1MB
    check --> Large : size >= 1MB
    Large --> fork
    fork --> Compress
    fork --> Scan
    Compress --> join
    Scan --> join
    join --> [*]
Choice, fork, and join — Mermaid state

size < 1MB

size >= 1MB

Small

Large

Compress

Scan

Try this snippet →

Concurrency and notes

stateDiagram-v2
    state Player {
        [*] --> Playing
        --
        [*] --> Unmuted
        Unmuted --> Muted : mute
    }
    note right of Player : two regions run in parallel
Concurrency and notes — Mermaid state

Player

Playing

mute

Unmuted

Muted

two regions run in parallel

A line with -- inside a composite state splits it into concurrent regions.

Try this snippet →

Common mistakes

These are the parse errors that come up most, including in code written by ChatGPT and Claude. Paste any failing diagram into the editor and it marks the offending line.

  • Using stateDiagram (v1) and getting different rendering or missing features.

    Fix: Always write stateDiagram-v2. The v1 renderer is kept only for backward compatibility.

  • State names with spaces used directly: In Review --> Published.

    Fix: Declare an alias first: state "In Review" as InReview, then use InReview.

  • Transition label with a colon in it (Review --> Done : approve: final).

    Fix: Only the first colon splits label from transition. Avoid additional colons or rephrase.

Real-world examples

Complete, copy-ready state diagrams for common situations. Each one opens in the editor with a click.

Browse all examples →

FAQ

How do I set the layout direction?

Add direction LR on the line after stateDiagram-v2. Composite states can set their own direction inside the braces.

Can I style a particular state?

Yes. classDef danger fill:#fee2e2,stroke:#dc2626 then class Error danger. Or pick a theme in MermanDraw to restyle everything consistently.