State diagrams
A state diagram shows the states of something and the events that move it from one to another: an order, a ticket, an agent run, a connection, a download, a release. Use it for a lifecycle or a state machine. It is for anyone, human or AI agent, who needs the answer to "what can happen next from here, and why".
TL;DR
| Question | Answer |
|---|---|
| What is it for? | A lifecycle or a state machine: states, the transitions between them, and the events, conditions and actions on each transition. |
| How does it start? | state "Title", then state id "Label" for a state and a -> b : "event [guard] / action" for a transition. The words start and end in a transition draw the start and end markers. |
| How do I make it readable? | One line per state: state paid "Paid" sub="Money received" tone=green icon=lucide:credit-card. Green is for success, amber for waiting, red for failure, and blue or violet for work in progress. See Make it readable. |
| What else can it hold? | Composite states with states inside, regions that run side by side, a choice, a fork and a join, a history marker, and notes. |
| Can I convert Mermaid? | Yes. stateDiagram and stateDiagram-v2 become a state diagram. They used to become a flow diagram. |
| How big may it be? | 300 nodes, 600 transitions and 6 levels of nesting. Past a limit the diagram is refused with error E140, before anything is drawn. |
| How is it drawn? | A rounded card for each state with an icon and a tint, a frame with a corner tab for a composite state, a dot and a ring for start and end, and a pill with a branch icon for a choice. Layout is automatic, and the theme chooses every color. |
Ask your agent
Say what the states are and what moves the thing from one to the next, then ask for an icon on every state and a color for what each state means. The agent writes the rest.
Use Plotwork to draw the lifecycle of an online order as a state diagram. An order starts as Pending, waiting for payment. A valid card payment moves it to a stock check, and nothing within 24 hours cancels it. If the item is in stock, it is picked and packed in a Fulfilment state and then delivered. If it is sold out, the order is cancelled and the money refunded. Give every state an icon, color the states by what they mean, and add a note that refunds stay open for 30 days.Use Plotwork to draw the run of an AI agent as a state diagram. The agent plans a step, then runs it with a tool, or waits for a person to approve it when the step is risky. A tool error is retried after a backoff while retries are left, and the run fails when they run out or when a person denies a step. The run is Done when the goal is met. Put an icon on every state, and use green for success, amber for waiting, and red for failure.Use Plotwork to draw the lifecycle of a subscription as a state diagram. A customer starts a 14 day trial, and is charged when it ends if a card is on file, or cancelled if not. An active subscription renews each period. A failed payment makes it Past due and is retried on days 3, 5, and 7, and after 21 days the subscription is cancelled and access is revoked. Give each state an icon and a tone that shows how healthy it is.Example
This is the order lifecycle from the first prompt. It shows a composite state with an icon of its own (Fulfilment, with its own start and end), a choice, transition labels that carry an event, a guard and an action, and a note.
state "Order lifecycle" desc="An order is paid, checked against stock, packed and delivered, or cancelled."
state pending "Pending" sub="Waiting for payment" tone=amber icon=status:pendingchoice stock "In stock?"state fulfilment "Fulfilment" icon=lucide:package { start -> picking state picking "Picking" tone=blue icon=lucide:clipboard-list state packed "Packed" tone=blue icon=lucide:package-check picking -> packed : "items scanned" packed -> end}state delivered "Delivered" tone=green icon=lucide:map-pinstate cancelled "Cancelled" sub="Money refunded" tone=red icon=status:error
start -> pendingpending -> stock : "pay [card valid] / charge card"pending -> cancelled : "timeout [after 24 hours]"stock -> fulfilment : "[in stock] / reserve items"stock -> cancelled : "[sold out] / refund"fulfilment -> delivered : "arrived"delivered -> endcancelled -> end
note cancelled : "Refunds stay open for 30 days"States:
- Start
- Pending (Waiting for payment), state
- In stock?, choice
- Fulfilment, composite state
- Start of Fulfilment
- Picking, state
- Packed, state
- End of Fulfilment
- Delivered, state
- Cancelled (Money refunded), state
- End
Transitions:
- Start of Fulfilment to Picking
- Picking to Packed on items scanned
- Packed to End of Fulfilment
- Start to Pending
- Pending to In stock? on pay, if card valid, then charge card
- Pending to Cancelled on timeout, if after 24 hours
- In stock? to Fulfilment, if in stock, then reserve items
- In stock? to Cancelled, if sold out, then refund
- Fulfilment to Delivered on arrived
- Delivered to End
- Cancelled to End
Notes:
- On Cancelled: Refunds stay open for 30 days
Make it readable
A state diagram reads fastest when the picture says how things stand before anyone reads a word. Four habits do that, and an agent can write all of them in one line per state, as the order lifecycle above does.
| Habit | How | Example |
|---|---|---|
| Color shows how it is going | tone=green for success, tone=amber for waiting or needing attention, tone=red for failure, tone=blue or tone=violet for work in progress, and no tone for a state at rest. | state failed "Failed" tone=red |
| One icon on every state | icon= names what the state is, so a card is clear at a glance. A status: icon has a tone of its own, such as status:success in green and status:error in red, and a simple: icon is the mark of a tool. | icon=lucide:credit-card, icon=status:error, icon=simple:docker |
One fact in sub= | The one detail that decides what happens next, such as a limit, a duration, or who acts. | sub="Waiting for payment" |
| The guard and the action in the label | The event says what happened, the guard in brackets says when the transition may run, and the action after a slash says what the system does. | "pay [card valid] / charge card" |
Keep a state name to a few words and move detail into sub= or a note: text wider than a card is cut with warning W203. Do not rely on color alone. The name and the icon say the same thing, so the diagram still reads for someone who cannot tell two tones apart. An icon name must exist, so ask search_icons or map_icons for it, and never invent one.
An AI agent run
An agent run shows tones that say how each step is going, a loop back to planning, and guards that choose between two transitions out of one state.
state "Agent run" desc="An agent plans, runs tools, waits for approval on risky steps, retries on errors, and finishes or gives up."
state planning "Planning" sub="Picks the next step" tone=violet icon=lucide:brainstate approval "Waiting for approval" sub="A person reviews the step" tone=amber icon=lucide:user-checkstate calling "Calling a tool" sub="Runs the step" tone=blue icon=lucide:square-terminalstate retrying "Retrying" sub="Backs off, then runs again" tone=amber icon=status:retrystate done "Done" sub="Goal met" tone=green icon=status:successstate failed "Failed" sub="Denied or out of retries" tone=red icon=status:error
start -> planning : "task received"planning -> approval : "step chosen [risky]"planning -> calling : "step chosen [safe]"approval -> calling : "approved"approval -> failed : "denied"calling -> planning : "result [goal not met]"calling -> done : "result [goal met]"calling -> retrying : "error [retries left] / wait"retrying -> calling : "backoff over"calling -> failed : "error [no retries left]"done -> endfailed -> end
note approval : "Times out after 10 minutes" side=topStates:
- Start
- Planning (Picks the next step), state
- Waiting for approval (A person reviews the step), state
- Calling a tool (Runs the step), state
- Retrying (Backs off, then runs again), state
- Done (Goal met), state
- Failed (Denied or out of retries), state
- End
Transitions:
- Start to Planning on task received
- Planning to Waiting for approval on step chosen, if risky
- Planning to Calling a tool on step chosen, if safe
- Waiting for approval to Calling a tool on approved
- Waiting for approval to Failed on denied
- Calling a tool to Planning on result, if goal not met
- Calling a tool to Done on result, if goal met
- Calling a tool to Retrying on error, if retries left, then wait
- Retrying to Calling a tool on backoff over
- Calling a tool to Failed on error, if no retries left
- Done to End
- Failed to End
Notes:
- On Waiting for approval: Times out after 10 minutes
A subscription lifecycle
A subscription shows a transition from a state to itself (the renewal), several ways into one state (Cancelled), and labels that carry an event, a guard and an action.
state "Subscription lifecycle" desc="A customer starts a trial, pays every period, may fall behind on payment, and cancels or lapses."
state trial "Trial" sub="14 days, then the first charge" tone=blue icon=lucide:timerstate active "Active" sub="Paid and in good standing" tone=green icon=lucide:badge-checkstate pastdue "Past due" sub="Payment failed, retrying" tone=amber icon=lucide:clock-alertstate cancelled "Cancelled" sub="Access ends with the period" icon=lucide:ban
start -> trial : "sign up"trial -> active : "trial ends [card on file] / charge"trial -> cancelled : "trial ends [no card]"active -> active : "period ends / renew"active -> pastdue : "payment failed / email customer"pastdue -> active : "payment succeeds"pastdue -> cancelled : "[after 21 days] / revoke access"active -> cancelled : "customer cancels"cancelled -> end
note pastdue : "Retries on days 3, 5, and 7" side=bottomStates:
- Start
- Trial (14 days, then the first charge), state
- Active (Paid and in good standing), state
- Past due (Payment failed, retrying), state
- Cancelled (Access ends with the period), state
- End
Transitions:
- Start to Trial on sign up
- Trial to Active on trial ends, if card on file, then charge
- Trial to Cancelled on trial ends, if no card
- Active to Active on period ends, then renew
- Active to Past due on payment failed, then email customer
- Past due to Active on payment succeeds
- Past due to Cancelled, if after 21 days, then revoke access
- Active to Cancelled on customer cancels
- Cancelled to End
Notes:
- On Past due: Retries on days 3, 5, and 7
A release pipeline
A release pipeline shows a fork and a join around checks that run in parallel, a choice on the result, and the brand icons of the tools from the simple set.
state "Release pipeline" desc="A push runs three checks in parallel, joins them, and ships only when all are green."
fork checksjoin gatechoice green "All green?"state push "Push" sub="To the main branch" icon=simple:githubstate lint "Lint" tone=blue icon=simple:eslintstate types "Type check" tone=blue icon=simple:typescriptstate test "Unit tests" tone=blue icon=simple:viteststate image "Build image" sub="Tagged with the commit" tone=violet icon=simple:dockerstate publish "Publish" sub="To the npm registry" tone=green icon=simple:npmstate fix "Fix" sub="Author is notified" tone=red icon=simple:git
start -> pushpush -> checks : "workflow starts"checks -> lintchecks -> typeschecks -> testlint -> gatetypes -> gatetest -> gategate -> greengreen -> image : "[all pass]"green -> fix : "[any fails] / notify author"fix -> push : "new commit"image -> publish : "image built"publish -> endStates:
- Start
- Fork checks, fork into parallel paths
- Join gate, join of parallel paths
- All green?, choice
- Push (To the main branch), state
- Lint, state
- Type check, state
- Unit tests, state
- Build image (Tagged with the commit), state
- Publish (To the npm registry), state
- Fix (Author is notified), state
- End
Transitions:
- Start to Push
- Push to Fork checks on workflow starts
- Fork checks to Lint
- Fork checks to Type check
- Fork checks to Unit tests
- Lint to Join gate
- Type check to Join gate
- Unit tests to Join gate
- Join gate to All green?
- All green? to Build image, if all pass
- All green? to Fix, if any fails, then notify author
- Fix to Push on new commit
- Build image to Publish on image built
- Publish to End
A connection that remembers its state
A live connection shows a composite state with a history marker, so a reconnect returns to Idle or Streaming, whichever was active when the network dropped.
state "Live connection" desc="A connection opens, drops, and comes back to the state it was in."
state connecting "Connecting" sub="Opens the socket" tone=blue icon=lucide:plugstate online "Online" tone=green icon=lucide:wifi { history last start -> idle state idle "Idle" sub="Heartbeats only" icon=lucide:radio state streaming "Streaming" sub="Receiving events" tone=aqua icon=lucide:zap idle -> streaming : "subscribe" streaming -> idle : "unsubscribe"}state reconnecting "Reconnecting" sub="Backs off up to 30 s" tone=amber icon=status:retrystate closed "Closed" icon=lucide:unplug
start -> connectingconnecting -> online : "socket open"online -> reconnecting : "network lost"reconnecting -> last : "reconnected / resubscribe"reconnecting -> closed : "[after 5 tries]"online -> closed : "close / send FIN"closed -> endStates:
- Start
- Connecting (Opens the socket), state
- Online, composite state
- Start of Online
- History of Online
- Idle (Heartbeats only), state
- Streaming (Receiving events), state
- Reconnecting (Backs off up to 30 s), state
- Closed, state
- End
Transitions:
- Start of Online to Idle
- Idle to Streaming on subscribe
- Streaming to Idle on unsubscribe
- Start to Connecting
- Connecting to Online on socket open
- Online to Reconnecting on network lost
- Reconnecting to History of Online on reconnected, then resubscribe
- Reconnecting to Closed, if after 5 tries
- Online to Closed on close, then send FIN
- Closed to End
A download with two regions
A download shows regions, two parts of one state that run side by side, and a transition from a state to itself.
state "Download manager" direction=down desc="A download runs its transfer and its progress display side by side, each as a region of one state."
state active "Downloading" icon=lucide:cloud-download { region "Transfer" { start -> connecting state connecting "Connecting" icon=lucide:plug state transferring "Transferring" sub="Reads blocks of 64 KB" tone=blue icon=lucide:download state verifying "Verifying" sub="Checks the SHA-256" tone=violet icon=lucide:shield-check connecting -> transferring : "connected" transferring -> transferring : "block / write to disk" transferring -> verifying : "last block" verifying -> end : "checksum matches" } region "Display" { start -> hidden state hidden "Hidden" icon=lucide:eye-off state shown "Progress shown" tone=blue icon=lucide:eye hidden -> shown : "window opened" shown -> hidden : "window closed" }}state failed "Failed" sub="Network lost" tone=red icon=status:errorstate finished "Finished" tone=green icon=status:success
start -> activeactive -> finishedactive -> failed : "network lost"failed -> active : "retry"finished -> endStates:
- Start
- Downloading, composite state
- Region Transfer
- Start of Downloading, region Transfer
- Connecting, state
- Transferring (Reads blocks of 64 KB), state
- Verifying (Checks the SHA-256), state
- End of Downloading, region Transfer
- Region Display
- Start of Downloading, region Display
- Hidden, state
- Progress shown, state
- Region Transfer
- Failed (Network lost), state
- Finished, state
- End
Transitions:
- Start of Downloading, region Transfer to Connecting
- Connecting to Transferring on connected
- Transferring to Transferring on block, then write to disk
- Transferring to Verifying on last block
- Verifying to End of Downloading, region Transfer on checksum matches
- Start of Downloading, region Display to Hidden
- Hidden to Progress shown on window opened
- Progress shown to Hidden on window closed
- Start to Downloading
- Downloading to Finished
- Downloading to Failed on network lost
- Failed to Downloading on retry
- Finished to End
The language
A line is one statement. A # starts a comment. Ids are words such as pending, in-stock or _x, labels are in double quotes, and options are written key=value. The first line is the header.
The header
state "Order lifecycle" direction=right desc="How an order moves from payment to delivery."| Part | Meaning |
|---|---|
state | The kind. |
"Title" | The title. It is the accessible name of the picture and heads the text description. Optional. |
direction= | auto (the default), right, down, left, or up. auto draws the diagram left to right and, when that is wider than a Markdown column, also top to bottom, and keeps the narrower one. |
desc= | A plain-language description for the text description. Optional. A desc "text" statement does the same. |
Statements
| Statement | Meaning | Example |
|---|---|---|
state <id> "Label" sub="Detail" tone=<tone> icon=<set:name> | A state, drawn as a rounded card. sub= is the description under the name, and a \n in it starts a new line. A tone other than neutral tints the card. icon= puts an icon before the name. | state paid "Paid" sub="Money received" tone=green icon=lucide:credit-card |
state <id> "Label" icon=<set:name> {, the states inside, then } | A composite state: a state that holds other states, drawn as a frame with its name, and its icon if it has one, in a corner tab. sub= goes in the tab as one line. The } is on a line of its own. | state shipping "Shipping" icon=lucide:package { |
<from> -> <to> : "event [guard] / action" | A transition. Every part of the label is optional. Only -> draws a transition. | pending -> paid : "payment received [card valid] / charge card" |
start -> <id> | The start marker of the scope the line is in: a filled dot. | start -> pending |
<id> -> end | The end marker of the scope the line is in: a ring with a dot. | delivered -> end |
choice <id> "Question?" tone=<tone> icon=<set:name> | A pill with a branch icon where one path splits on conditions. The question is optional: with none it is a small round chip holding only the icon. The default tone is amber, icon= swaps the icon, and icon=none drops the chip. | choice stock "In stock?" |
fork <id> | A bar where one path splits into parallel paths. | fork split |
join <id> | A bar where parallel paths merge. | join merge |
history <id> deep=on | A circle holding H, or H* with deep=on, inside a composite state. A transition into it returns to the state that was active last. | history last deep=on |
region "Name" {, the states inside, then } | One of the parts of a composite state that run side by side. The name is optional. | region "Reader" { |
note <id> : "text" side=<side> | A note on a state, a choice, a bar, or a composite state. side= is left, right, top, bottom, or left out. | note paid : "Refunds stay open for 30 days" side=right |
desc "text" | The description of the diagram. | desc "How an order moves." |
tone= takes neutral, blue, violet, aqua, orange, green, amber, or red, and icon= takes a name from the closed list of icons, such as lucide:play, status:success or simple:github. A diagram cannot set a color: the theme chooses every color, in light and dark. Make it readable says which tone and icon to choose.
The transition label
The label of a transition reads event [guard] / action, as in UML. The parser splits it, so the picture sets the event in the primary ink and the guard and the action in the secondary ink, and the text description says "on the event, if the guard, then the action".
| Written | Event | Guard | Action |
|---|---|---|---|
payment received | payment received | none | none |
[in stock] | none | in stock | none |
pay [card valid] / charge card | pay | card valid | charge card |
close / send FIN | close | none | send FIN |
/ notify support | none | none | notify support |
GET /orders | GET /orders | none | none |
array[0] access | array[0] access | none | none |
A slash starts the action only when a space follows it, and brackets are a guard only when they are the last thing before the action or the end of the label. So GET /orders and array[0] access are events. Text wider than 300 px is cut with an ellipsis and warning W203; the full text stays in the text description.
Start, end, and scopes
A scope is the top level of the diagram, a composite state, or one region.
| Rule | Detail |
|---|---|
start and end are words, not ids | state start "Start" is error E360. A transition into start or out of end is error E361. |
| A scope has one start and one end | The marker is made the first time a transition in that scope names it, however many transitions name it. |
| The marker belongs to where the line is written | start -> a inside state shipping "Shipping" { is the start of Shipping. |
| A transition may cross scopes | Ids are global, so a line inside one composite state may name a state in another. |
| A transition may enter or leave a composite state by its id | order -> shipping enters at the start marker of Shipping, and shipping -> delivered leaves from its frame. A transition between a composite state and a state inside it is error E365. |
| A state may loop to itself | A composite state may too. A choice, a bar, a marker, or a history marker may not (E364). |
Regions
A region goes directly inside a composite state, and a composite state holds either states or regions, never both (E362). A region outside a composite state, or inside another region, is E363. Each region has its own start and end markers. A diagram that reads sideways stacks its regions, a diagram that reads up or down puts them in a row, and a dashed line crosses the whole frame between two of them. A download with two regions draws this.
state sync "Syncing" { region "Upload" { start -> sending state sending "Sending" icon=lucide:cloud-upload } region "Download" { start -> receiving state receiving "Receiving" icon=lucide:cloud-download }}Forks, joins, and choices
A fork splits one path into parallel paths and a join brings them together, so use them when several things must all happen. A choice splits one path on conditions, so give every branch out of it a guard. A release pipeline uses both.
fork splitjoin mergechoice green "All green?"
split -> lintsplit -> testlint -> mergetest -> mergemerge -> greengreen -> deploy : "[yes]"green -> fix : "[no]"History
A history marker sits inside a composite state. A transition into it returns to the state that was active last, and deep=on makes it remember the state of nested composite states too. It is an error outside a composite state (E366). A connection that remembers its state draws this.
state player "Player" { history last deep=on start -> stopped state stopped "Stopped" state playing "Playing" icon=lucide:play stopped -> playing : "play" playing -> stopped : "stop"}state off "Off"
start -> playerplayer -> off : "power"off -> last : "power"Notes
A note sits across the reading direction, so a transition, which runs along it, never meets one. side= is a request: a side along the reading direction moves to the nearest side across it.
| The diagram reads | left | right | top | bottom | No side |
|---|---|---|---|---|---|
| Right or left | above | below | above | below | below |
| Down or up | left | right | left | right | right |
Notes on one side stack in the order they are written, nearest first, and a dotted line joins each note to its state. A note on a composite state has no free side, so it sits inside the frame, under what the frame holds, with no connector. A note on a start or end marker is error E367.
Limits and warnings
Warnings never stop a diagram from being drawn. Errors do.
| Limit | Value | What happens past it |
|---|---|---|
| Nodes of any kind | 300 | E140 |
| Transitions | 600 | E140 |
| Layers skipped by transitions | 400 | E140 |
| Nesting of composite states | 6 | E140 |
| Regions in one composite state | 8 | E140 |
| Notes | 100 | E140 |
| States before the density warning | 15, plus 1 for each composite state, up to 25 | W200 |
| Nesting before the warning | 3 | W334 |
Layers skipped counts how far transitions jump over the rest of the diagram: a transition that passes over many layers makes the layout work much harder than the number of states suggests, so that number is limited, not only the number of states. The limits are checked from the text alone, so a diagram that is too big is refused at once with a hint on how to split it.
| Code | Severity | When | Fix |
|---|---|---|---|
E360 | error | start or end is used as an id. | Pick another id, and write the marker as a transition. |
E361 | error | A transition goes into start or out of end. | The marker only begins or finishes a transition. |
E362 | error | A composite state holds both states and regions. | Put the state into a region. |
E363 | error | A region is outside a composite state, or inside a region. | Open it inside a composite state. |
E364 | error | A choice, a bar, a marker, or a history marker loops to itself. | Loop through a state. |
E365 | error | A transition joins a composite state and a state inside it. | Start the transition from inside. |
E366 | error | A history is outside a composite state. | Put it inside the composite state it belongs to. |
E367 | error | A note is on a start or end marker. | Attach it to the state next to the marker. |
E140 | error | The diagram is over a limit in the table above. | Split the diagram. |
E100, E101, E110, E111, E121 to E123, E130, E131, E133 to E136 | error | The shared codes: a syntax error, an unterminated string, an unknown statement or header, an unknown tone, icon, or direction, a duplicate id, an unknown state, an unclosed or unmatched block, an unknown option, or a bad option value. | The message names the line and says what to write. For an unknown state it gives the nearest id. |
W200 | warning | There are more states than the density limit. | Group states into composite states, or split the diagram. |
W201 | warning | A state has no transition at all. | Connect it or remove it. |
W202 | warning | The diagram is wider than a column would keep readable. | Use direction=down, shorten the labels, or split it. |
W203 | warning | Text was cut with an ellipsis. | Shorten the text, or move the detail into sub= or a note. |
W330 | warning | No path from the top-level start reaches a state. | Add a transition into it. |
W331 | warning | A state has no way out, in a part of the diagram that has an end. | Add a transition out, such as name -> end. |
W332 | warning | A choice has fewer than two ways out, or a branch has no condition. | Give every branch a guard. |
W333 | warning | A fork has fewer than two transitions out, or a join has fewer than two in. | Give it two, or use a state. |
W334 | warning | Composite states are nested more than 3 deep. | Flatten them, or draw the inner machine as its own diagram. |
W330 is checked only when the top level has a start marker, and a composite state with no start of its own begins wherever nothing leads into it. W331 looks at one scope at a time: a state is a dead end only when its own scope has an end marker and neither it nor a composite state around it has a transition out.
From Mermaid
stateDiagram and stateDiagram-v2 convert into a state diagram. Before the state kind existed they were converted into a flow diagram, with the start and end as nodes and each composite state as a group. The converter now writes a state diagram, checks it, and returns nothing for one that would not validate. Call convert_mermaid on one diagram, or sync_markdown with convertMermaid for a whole file, as the migration guide describes. The conversion adds no icons and keeps no colors, apart from a tone taken from a class name such as error, so choose a tone and an icon for each state afterwards, as Make it readable describes.
---title: Print job---stateDiagram-v2 [*] --> Queued Queued --> Printing : printer free Printing --> Done Printing --> Failed : jam Failed --> Queued : retry Done --> [*] state Printing { [*] --> Warming Warming --> Spooling Spooling --> [*] } note right of Failed : Paper jams are the usual cause classDef bad fill:#f96 class Failed badThe converter writes this, and reports two warnings M200 for the dropped classDef and class lines:
state "Print job"
state Queued "Queued"state Printing "Printing" { state Warming "Warming" state Spooling "Spooling"
start -> Warming Warming -> Spooling Spooling -> end}state Done "Done"state Failed "Failed"
start -> QueuedQueued -> Printing : "printer free"Printing -> DonePrinting -> Failed : "jam"Failed -> Queued : "retry"Done -> end
note Failed : "Paper jams are the usual cause" side=rightWhat is kept
| Mermaid | Plotwork | Note |
|---|---|---|
A --> B : event | a -> b : "event" | The label is kept as written. A chain such as A --> B --> C : x is two transitions, with the label on the last. |
state A, state "Long name" as A | state a "Long name" | The id stays. A state first mentioned in a transition is declared when the diagram is written. |
A : description | sub="line one\nline two" | Each description line stays its own line. |
[*] --> A, A --> [*] | start -> a, a -> end | The marker of the scope the line is in. Inside a composite state it is that state's own. |
state A { and its states | state a "A" { and its states | Nesting is kept up to 24 levels (M102 past that). A transition into or out of the composite state is kept as written. |
-- inside a composite state | region blocks | What comes before the first -- is the first region. One region alone is no split. |
<<choice>>, [[choice]] | choice id | |
<<fork>>, <<join>> | fork id, join id | They are bars now, so there is no warning. |
note right of A : text, or a note with end note | note a : "text" side=right | A multi-line note joins its lines with a space. A note on a state that was never mentioned declares it. |
direction LR | direction=right in the header | TB and TD give down, BT up, and RL left. |
accTitle, accDescr, a front matter title: | The title and desc= | A front matter title wins. |
%% comment, on a line of its own or at the end of one | Ignored | A %% inside quotes is text. |
What is dropped or changed
| Mermaid | What happens | Code |
|---|---|---|
classDef, class, :::name, style, %%{init}%%, front matter config: | Dropped. A class name that means a tone (error, danger and fail give red, warning gives amber, and success, ok, done and pass give green) gives the state that tone=, and the class itself is dropped. | M200, and M207 for the tone |
click | Dropped. A diagram is a static picture with no links inside it. | M201 |
scale, hide empty description, and a direction inside a composite state | Dropped. Plotwork chooses the scale and has one reading direction for the whole diagram. | M202 |
A -- outside a composite state, a transition that loops a choice or a bar to itself, and a transition between a composite state and a state inside it | Dropped, because the meaning has no Plotwork form. | M203 |
A stereotype Plotwork has no shape for, such as <<expandable>> | Drawn as a plain state. | M204 |
HTML tags, Markdown marks, line breaks and entities such as " in a label | Decoded or removed. | M205 |
| An id that is not a valid Plotwork id | Renamed. The label keeps the original name. | M206 |
| An exact repeat of a transition | Dropped. | M209 |
| An empty composite state, an empty region, or an empty description | The composite state becomes a plain state, and the empty region is dropped. | M216 |
A composite state or a note that is never closed, or a } that closes nothing | Repaired. | M217 |
| A line that cannot be read | An error, or with lenient a warning that skips the line. | M110, M218 |
| A note on a composite state | Drawn inside its frame, under the states it holds, because the frame has no free side. | M250 |
A state named start or end | Renamed (start_state), because the markers use those words. | M251 |
The old conversion differed in ways that matter if you kept its output. A state was node id step "Label" and is now state id "Label", with no node types. The start and end were terminal nodes with ids such as start_Active and are now markers written as transitions. A note and a -- were dropped and are now kept, as a note and as regions. A transition into a composite state was redrawn to its start node, and is now kept as written. <<fork>> and <<join>> were plain steps and are now bars.
See also
| Doc | Why |
|---|---|
| Writing diagrams | The flow, sequence, and schema kinds, and the options every kind shares |
| Examples to copy | Finished diagrams with the prompt that gets an agent to write each one |
| Migrating from Mermaid | The converter, its diagnostic codes, and what carries over |
| Icon reference | Every icon name you can put in icon= |
| Git graphs | A repository history drawn as lanes |
| Gantt charts | A plan drawn on a calendar |
| Class diagrams | Classes, their members, and how they relate |
| Timelines | Events in time order |
| User journeys | The steps of a person, scored by how they feel |
| Mind maps | An idea and its branches |
| Language reference | Every word of the language, one page for each topic |
| Diagram kinds | The kinds, and what each one draws |