Skip to content
Connect an agent
Get started

Writing diagrams

How to write flow, sequence, and schema diagrams in the diagram language, with a pointer to the guide of each of the seventeen other kinds. There are twenty kinds in all. It is for anyone, human or AI agent, who writes diagram source. Every example on this page is a real diagram, rendered by the tool this guide teaches, so you can copy one and it works.

TL;DR

RuleYesNo
StatementsOne per lineTwo statements on one line
LabelsQuoted: "Auth API"Bare words with spaces
MeaningA node type (database) or a tone= (violet)A color value such as #7c3aed; colors are not accepted
IdsShort and stable: api, user_db, as-jwksSpaces, or an id reused for two things
Iconsicon=lucide:key, icon=simple:postgresql, icon=aws:lambda, icon=status:successA made-up name; it is rejected with suggestions
GroupsA name and a type for what the group is: group vpc "Application VPC" type=network {A color, or a long sentence as the name
SizeAbout 15 nodes, 6 tables, or 6 actors at mostOne diagram that tries to show everything
LabelsShort, in sentence caseA paragraph inside a node
Step numbersnumbered=on in the header, step=off on a line to skip oneA number typed into each label

1. How a diagram starts

The first line names the kind, gives a quoted title, and may add options. The title becomes the accessible name of the picture.

KindHeaderOptions
Flowflow "Title"direction= (auto, right, down, left, up), desc="Summary", animate=on, numbered=on, start=
Sequencesequence "Title"desc="Summary", animate=on, numbered=on, start=
Schemaschema "Title"desc="Summary"
Git graphgit "Title"direction=, main=, desc=. See Git graphs.
Gantt chartgantt "Title"start=, unit=, today=, weekends=, holidays=, desc=. See Gantt charts.
Class diagramclass "Title"direction=, desc=. See Class diagrams.
State diagramstate "Title"direction=, desc=. See State diagrams.
Timelinetimeline "Title"direction=, side=, desc=. See Timelines.
User journeyjourney "Title"marks=, legend=, desc=. See User journeys.
Mind mapmindmap "Title"layout=, desc=. See Mind maps.

desc is a one- or two-sentence summary. It is used as the picture's alt text, so write what the diagram says. animate, numbered, and start are explained in Numbered steps and Animated lines.

Lines that start with # are comments.

2. Flow diagrams

A flow diagram shows things and the connections between them. Use it for architecture and for processes.

StatementFormNotes
Nodenode <id> <type> "Label" sub="Detail" tone=blue icon=lucide:key stack=simple:gosub, tone, icon, and stack are optional. stack= adds up to three technology marks under the text.
Groupgroup <id> "Name" type=network provider=aws {, then nodes, then }type, provider, icon, and tone are optional. Groups nest. type= says what the group is and sets its icon, tone, and frame style.
Edgea -> b : "label" icon=status:yes role=data animate=off step=12The label, the icon, role=, animate=, and step= are optional. An icon needs a label. A label that names a relationship with a verb, such as reads or publishes OrderPlaced, draws its icon by itself.

Arrows:

TokenMeaning
->Solid line, arrowhead at the end
-->Dashed line, arrowhead at the end
..>Dotted line, arrowhead at the end: an asynchronous call such as a webhook or an event
<-> and <-->Arrowheads at both ends
--A line with no arrowhead

Where one line crosses another at a right angle, the horizontal one hops over the other with a small arc, so a reader sees a crossing and not a join, in solid and dashed lines alike. Lines that meet or share a stretch are not crossings and do not hop. A bend right beside a hop tightens a little to make room, and a hop is left out where it would still land on a bend, an arrowhead, a node, or a label. There is nothing to write for it.

A node's type sets its default icon, tone, and look. The flow node types page lists every type. These are the most used:

TypeUse for
person, agent, clientWho or what starts things
service, gateway, functionCode that runs
database, cache, queue, storageWhere data lives
identity, secretTrust and credentials
externalSystems you do not own (dashed outline)
step, decision, terminalProcess steps, branches, and end states

A group draws a frame around its nodes and carries a corner tab: a small box fixed to the frame's top-left corner that holds the group's icon and its name on one line. The tab grows to fit the name, with the same padding on both sides. A name that is longer than the widest node card is cut with an ellipsis and warning W203, so keep a group's name to a few words and put detail in the nodes.

Group optionEffect
type=<type>What the group is, from a closed list such as account, region, network, subnet, data-tier, or trust-boundary. It sets the icon, the tone, and a solid, dashed, or dotted frame.
provider=<provider>Whose resources the group holds (aws, azure, gcp), so a type draws that provider's icon. Nested groups inherit it.
icon=<set>:<name>Overrides the icon in the tab. A group with no type has none unless you set one.
tone=<tone>Overrides the tone. Without a type the group is neutral.
sub="..."A short second line in the tab under the name, such as an address range.
stack=<set>:<name>,...Up to three small marks in the tab, written like the marks of a node.
icon=noneRemoves the icon.
type=noneKeeps the group plain: no type from its name and no suggestion.

A group with no type= whose name gives its type for certain takes it by itself: VPC, Production, CI pipeline, Kafka, Kubernetes, us-east-1, Data, Security, and Monitoring are typed, while Data science team and Data pipeline stay plain. A name that only suggests a type gets warning W205 with the type= to add. icons=off on the header turns this off along with the automatic icons.

An overlay draws a dashed frame around nodes or groups it does not own, wherever layout put them. It is one line after the members, overlay set "Web machines" type=scale-group members=w1,w2,w3, and it takes type=, provider=, icon=, tone=, sub=, and stack= like a group. Use it for a scaling group that spans two zones or a redundant set of machines inside a tier. When the members sit in different groups, the frame crosses the group frames on purpose, and warning W206 says if it would also surround a node that is not a member.

A group nested in another is shaded one step stronger than the one around it, in light and in dark. The group types page draws every group type and the icon each draws for each provider, the cloud architecture guide has the recipe and the icon pages for every cloud product, and the architecture patterns guide has ready-made diagrams for the common shapes.

An edge that would pass under a tab is moved to the side when the nodes it joins allow it, and otherwise passes behind the tab.

Nested groups and directions: 5 nodes, 4 connections. A request crosses a trust boundary into a private network containing an API and its data stores.

Make it look finished

Four habits make a flow diagram look finished without a single colour value:

HabitWriteWhat it draws
A verb on each arrowapi -> db : "reads orders"The relationship's icon in the label: an eye for reads, a pen for writes, a paper plane for publishes, a rocket for deploys
A role on the lines that mean somethingrole=data, role=async, role=identity, role=privateThe line in the role's colour, named in a legend. Warning W500 lists the arrows to mark
A type on each grouptype=network, or a name such as "Production"The frame, tone, and icon of the kind
Product names on nodes"Postgres", "Redis", "Amazon S3"The product's mark

W204, W205, and W500 are style suggestions: validate --strict and the Action's fail-on: warning pass them.

Checkout: 6 nodes, 5 connections. A web app calls the checkout API, which writes orders to Postgres, reads sessions from Redis, and publishes an event that an email worker consumes.

3. Sequence diagrams

A sequence diagram shows messages between actors over time. Use it for protocols, login flows, and code paths.

StatementFormNotes
Actoractor <id> <type> "Label" sub="Detail" icon=lucide:key tone=blueDeclared in column order, left to right.
Messagea -> b : "label" animate=off step=offUse --> for a reply. a -> a is a message to itself. animate= and step= are optional.
Notenote over a : "text" or note over a, b : "text"The second form spans several actors.
Framealt "condition" {, messages, } else "other" {, messages, }Also opt, loop, and par (with and for the next branch).

A message between two actors that are not neighbours crosses the lifelines of the actors between them. Each crossing is drawn as a small arc that the arrow hops over, so a reader sees a crossing and not a join, in solid and dashed arrows alike. There is nothing to write for it.

Checkout with retries: 4 participants. A client pays for an order. The payment is retried up to three times, and inventory is updated in parallel with the receipt.

4. Schema diagrams

A schema diagram shows database tables, their columns, and the relations between them.

StatementFormNotes
Tabletable <name> sub="Detail" icon=lucide:table tone=aqua {, then columns, then }sub, icon, and tone are optional.
Column<name> <type> pk fk unique nullable note="Why"Flags and note are optional and may be combined.
Relationchild.column -> parent.column : "label"Written from the referencing column to the referenced one. The label is optional; leaving it out keeps wide schemas narrower.

A relation draws a crow's foot at the many end. It draws a single tick at the one end, and at both ends when the referencing column is unique.

Orders: 3 tables, 2 relations. Orders belong to customers; each order has one invoice and many items.

5. Icons

Every node, actor, table, and group can carry one icon, set with icon=<set>:<name>. A group shows its icon in its corner tab.

SetContentsExample
lucideGeneral iconsicon=lucide:key-round
simpleTechnology and brand logosicon=simple:postgresql
statusColored outcome iconsicon=status:success
aws, gcp, azure, alibaba, oci, ibm, cloudflare, digitalocean, vercelA provider and its productsicon=aws:lambda, icon=gcp:bigquery, icon=azure:functions, icon=alibaba:oss

Find a name with the search_icons tool, or ask your agent to choose icons for you. Search matches ideas as well as names: token exchange, validate, revoke, timeout, and bug each find suitable icons. It also knows products: lambda, s3, gke, cosmos db, bigquery, and serverless function find the right provider icon first. The icon reference shows every icon. A name that does not exist is an error with a suggestion, so a typo never renders as a blank space, and a guessed provider such as amazon:s3 is pointed at aws:s3.

Status icons keep their own color on any node: green for good, red for bad, amber for caution, blue for information, and neutral for waiting. The full list, with meanings, is in the language reference.

Deployment pipeline: 4 nodes, 3 connections. A change is built, tested, and deployed. A failed test stops the pipeline.

Cloud architecture

Name a product with its provider and its own name: aws:lambda, gcp:pubsub, azure:entra-id. Give the group that holds a cloud's resources type=account and its provider=, which draws the provider's own icon (<provider>:cloud), and nest a type=region group for each region. The cloud architecture guide covers the whole recipe, and the icon pages (AWS, Azure, Google Cloud) draw every product. Where a provider publishes an official icon for a product, or has a licensed brand mark, the icon draws it; every other product draws the glyph for its kind of service, so a function looks like a function whichever cloud it runs on. The label says whose it is.

Multi-cloud order platform: 9 nodes, 8 connections. Orders enter through AWS, are stored and queued in one region, replicated to Google Cloud for analytics, while customers sign in through Azure.

6. Decisions and outcomes

A decision node is a tinted card with a branch icon. Label the outgoing edges with the answers. A label that is exactly yes or true gets a green tick, and no or false gets a red cross, without any extra syntax. Add icon= to an edge for another icon, or icon=none to remove the automatic one. A terminal node is a pill, and it can carry a status icon for the outcome.

Review outcome: 4 nodes, 3 connections. A pull request is approved or sent back for changes.

7. Numbered steps

Add numbered=on to the header of a flow or a sequence diagram and every line gets a numbered badge, counting in the order the lines are written. In a sequence diagram the badge sits on the message, and the messages inside alt, opt, loop, and par blocks are numbered in the order they are read. In a flow diagram it sits on the connection. Use it for a procedure, a protocol, or a runbook, where a reader says "step 4" aloud.

WhereOptionWhat it does
Headernumbered=onNumbers every line, starting at 1.
Headerstart=5Starts at 5 instead. A whole number from 0 to 999, and it needs numbered=on.
One linestep=offDraws no badge on this line, and uses up no number.
One linestep=12Gives this line the number 12. The lines after it continue from 13.

A step= on a line of a diagram that is not numbered is an error, and so is a count that runs past 999. A sequence diagram:

Sign in with an emailed code: 4 participants. A user asks for a code, receives it by email, and trades it for a session. Each message carries its step number.

A flow diagram, where the number sits on each connection:

Release steps: 5 nodes, 4 connections. A change is pushed, built, published as an image, and deployed. Each connection carries its step number.

8. Animated lines

Add animate=on to the header of a flow or a sequence diagram and every line that has an arrowhead gets moving dashes that travel toward the head. It shows which way data or control goes, which suits a pipeline or a request path. To animate one line only, write animate=on on that line. To keep one line still while the header animates the rest, write animate=off on it.

RuleWhat happens
animate=on in the headerEvery line with an arrowhead moves. A -- line has no arrowhead, so it stays still.
animate=off on a lineThat line stays still, whatever the header says.
animate=on on a -- lineAn error, because dashes travel toward an arrowhead and the line has none. Use ->, or remove the option.
A line with two arrowheads (<->)It moves from its first end to its second.

The motion is part of the SVG, so it moves wherever a browser shows the SVG as an image, including a README on GitHub and this page. It stays still in a PNG and in a reader that flattens the SVG into a picture, and it is switched off when the reader asks for reduced motion in their system settings. The picture means the same thing without it, so never rely on motion to say something that the text does not.

Events into the warehouse: 5 nodes, 5 connections. Events flow from an app through an API and a queue to a processor, which stores them. The acknowledgement is drawn still.

9. Fitting text

Text never overflows its box, and padding stays the same on every box.

SituationWhat happens
A label is longer than a cardIt wraps onto more lines, up to three, and the card grows taller.
One word is longer than a cardThe card widens to hold it, up to 400px.
Text is still too longIt is cut with an ellipsis and the diagram gets warning W203. The full text stays in the text description.
A group name is longThe corner tab grows to fit it on one line, up to the width of the widest card (400px). Past that the name is cut with an ellipsis and warning W203.
A message label is long in a sequence diagramThe columns spread apart to make room, and W202 appears if the diagram then becomes too wide.

The fix for a warning is almost always shorter text. Move detail into sub=, a note, or the prose around the diagram.

10. Quality warnings

Warnings never stop rendering. They point at things a reader will notice.

CodeMeaningFix
W200Too many nodes, tables, or actorsSplit along a group boundary or by domain.
W201A node is not connected to anythingConnect it or remove it.
W202The diagram is wider than a Markdown column and its text would shrinkUse direction=down, shorten labels, or split it.
W203Text was cut with an ellipsis, in a node, an actor, or a group nameShorten the text.
W204A node has no icon=, and its label names one productAdd the icon= the warning gives, or write icon=none.
W205A group has no type=, and its name matches one group typeAdd the type= the warning gives.

See also

DocWhy
Cloud architectureTyped groups, provider icons, and how to map a product name to an icon
Architecture patternsReady-made, checked diagrams to start from
Language referenceEvery type, tone, icon, arrow, and diagnostic code
Writing diagrams with an agentThe validate and fix loop
Diagrams in Markdown and on GitHubPutting diagrams in a document
How a diagram is drawnWhat happens between your text and the picture