Skip to content
Connect an agent
Language reference

Diagram kinds and settings

The twenty kinds of diagram with an example of each, and the settings a diagram accepts: tones, directions, themes, sequence frames, and schema column flags.

TL;DR

QuestionAnswer
What starts a diagram?A header line naming the kind and a quoted title: flow "Title", sequence "Title", schema "Title", git "Title", gantt "Title", class "Title", state "Title", timeline "Title", journey "Title", mindmap "Title", treemap "Title", pie "Title", quadrant "Title", layers "Title", c4 "Title", matrix "Title", sankey "Title", xychart "Title", tree "Title", swimlane "Title".
Who picks colors?The theme. Authors choose a type or a tone (neutral, blue, violet, aqua, orange, green, amber, red), never a color value.
Which directions can a flow take?auto, right, down, left, up, written direction=<value> on the header.
Where is each kind explained in full?Flow: Flow node types, Groups and overlays, and Arrows and edge labels. Sequence and schema: Writing diagrams.

Diagram kinds

KindHeader line
flowflow "Title"
sequencesequence "Title"
schemaschema "Title"
gitgit "Title"
ganttgantt "Title"
classclass "Title"
statestate "Title"
timelinetimeline "Title"
journeyjourney "Title"
mindmapmindmap "Title"
treemaptreemap "Title"
piepie "Title"
quadrantquadrant "Title"
layerslayers "Title"
c4c4 "Title"
matrixmatrix "Title"
sankeysankey "Title"
xychartxychart "Title"
treetree "Title"
swimlaneswimlane "Title"

Examples

C4: Internet banking system

Internet banking system: container view, 8 elements, 1 boundary, 10 relationships. The containers of the internet banking system and the people and systems around it.

Class: Notification service

Notification service: 7 classes, 1 package, 6 relations. A notifier queues messages and delivers each one through a channel. Channels are interchangeable, so a new one needs no change to the notifier.

Flow: Login request

Login request: 4 nodes, 4 connections. A user signs in through an API that checks credentials in a database and keeps the session in a cache.

Gantt: Product launch plan

Product launch plan: 10 tasks and 2 milestones in 4 sections, from 2026-01-05 to 2026-04-14. A fourteen week plan from research to launch, with design and build running side by side.

Git: Release and hotfix

Release and hotfix: 10 commits on 4 branches, 3 merges, 1 cherry-pick, 2 tags. A feature is merged into develop, develop is released as v1.0, and a hotfix is tagged and picked back.

Journey: Checkout experience

Checkout experience: 7 tasks in 3 stages, average satisfaction 3.4 of 5. How a shopper feels from finding a product to holding the parcel, and who is involved at each step.

Layers: Online banking platform

Online banking platform: 4 layers, 14 blocks, 1 aside, 6 links. A customer reaches accounts, payments and cards through one gateway. Each layer calls the layer below it, and security and monitoring cut across all of them.

Matrix: Message broker options

Message broker options: 4 rows compared on 5 columns. Recommended: Kafka. Four message brokers compared on five criteria. Kafka is the pick for the event pipeline because it keeps order at the highest throughput.

Mindmap: Product launch

Product launch: 24 topics, 5 branches, 2 levels. What the team settles before the product ships: who it is for, what it is, where to say so, and what could go wrong.

Pie: Where visits come from

Where visits come from: 6 slices of 44,500 in all, the largest Search at 42%. The share of one month's visits to the docs by the channel that sent them: search brings the most, then people who typed the address.

Quadrant: What to build next

What to build next: 14 points placed by Effort and Impact. Fourteen roadmap ideas placed by the effort they take and the impact they have on customers. The quick wins in the top left are the ones to start with.

Sankey: Request traffic through the platform

Request traffic through the platform: 10 nodes and 13 flows in 4 columns, total 12,000 req/s. How 12,000 requests per second move from the edge through the API gateway and three services to the data stores, with blocked and failed requests branching off.

Schema: Users and sessions

Users and sessions: 2 tables, 1 relation. Each session belongs to one user.

Sequence: Token refresh

Token refresh: 2 participants. A client refreshes an expired access token, or is told to sign in again.

State: Order lifecycle

Order lifecycle: 6 states (1 composite), 11 transitions. An order is paid, checked against stock, packed and delivered, or cancelled.

Swimlane: Order fulfilment

Order fulfilment: 4 lanes, 10 steps, 10 transitions. A customer's order is checked against stock, paid for, packed and shipped, or cancelled.

Timeline: Orbit product history

Orbit product history: 6 periods and 10 events in 3 sections. From a weekend prototype to a platform that teams run their work on.

Tree: storefront

storefront: file tree of 17 entries (10 folders, 7 files), 4 levels, 1 changed, 9 more not drawn. The layout of a small repository: services, libraries, and the file a change touches.

Treemap: Monthly cloud spend

Monthly cloud spend: 17 items in 5 groups, total $81,700. Where the monthly cloud bill goes, by service, with the change since last month. A rise in cost is drawn red.

Xychart: API latency against the SLO

API latency against the SLO: 2 series (bar and line) over 8 places on the Week axis, on a scale of 0 ms to 500 ms. Weekly p50 and p95 latency of the checkout API against its 400 ms objective: p95 crossed the line after release 2.3 and came back under it after the cache fix.

Statements by kind

Git graph

Branches as lanes, with the commits, merges, and tags along them, for a repository history. The header line is git "Title".

StatementWhat it doesExample
git "<title>" direction=<auto|right|down> main=<name> desc="<summary>"The header, and the first line. Every option is optional. direction=auto, the default, draws one lane per row with time running left to right when that fits a column of the page, and one lane per column with time running down the page when it does not. direction=right and direction=down fix it. main= names the default branch, which is main unless you say otherwise.git "Release flow" direction=right main=trunk desc="A feature branch merges into the trunk and the release is tagged."
commit "<message>" id=<id> tag="<name>" type=<normal|highlight|reverse>A commit on the current branch. Statements are written in time order: the order written is the order in time. Every part after the word is optional, and a commit with no message is a bare dot. id= names the commit for cherry-pick and from=; an id is drawn only on a commit that a cherry-pick copies. tag= puts a tag on the commit; repeat it or list names with commas, up to 3. type=highlight draws a milestone with a halo, and type=reverse a ring with a cross for a revert. Valid types: normal, highlight, reverse.commit "Add search" id=c2 tag="v0.2" type=highlight
branch <name> from=<branch or id> order=<n> tone=<tone>Makes a branch at the newest commit of the current branch, or of from=, and switches to it. A name with a slash goes in double quotes: branch "feature/search". from= takes a branch name or a commit id, so a hotfix can start from an old release. order= moves the lane: the lowest order is the first lane, a branch with no order takes the number of branches made before it, and order=1 is the second lane. tone= sets the lane color. A branch needs a commit to start from, so write a commit first.branch "feature/search" from=develop order=2
checkout <branch>Switches the current branch, so the commits that follow go on it. switch is another spelling. The branch must already exist.checkout develop
merge <branch> "<message>" id=<id> tag="<name>" type=<type>A merge commit on the current branch that brings in the newest commit of another branch, drawn with a ring in the color of the merged branch and a line from that branch. The message and the options are optional. A branch cannot be merged into itself, and merging one that is already part of the current branch adds nothing, which draws warning W300.merge develop "Release 1.0" tag="v1.0" type=highlight
cherry-pick <id> "<message>" tag="<name>"A copy of one commit, made on the current branch and drawn with a dashed ring in the color of the lane it came from. The commit is named by its id=, so give the source commit an id. With no message the copy keeps the message of the commit it copies. A commit the current branch already has cannot be picked.cherry-pick c3 tag="v1.0.1"
desc "<summary>"The plain-language summary, as a statement of its own, for people who prefer it to desc= on the header.desc "Hotfix 1.0.1 is picked back onto main."

Gantt chart

Tasks and milestones on a time axis, in sections and with dependencies, for a project schedule. The header line is gantt "Title".

StatementWhat it doesExample
gantt "Title" start=<date> end=<date> unit=<day|week|month|quarter|year> today=<date> weekends=<show|shade|skip> holidays=<dates> desc="<text>"The header. Every option is optional. start= and end= can only widen the axis, never cut a task. unit= is the step of the axis (the default follows the span of the plan). today= draws a marker on that day, and there is none without it. weekends=shade tints Saturdays and Sundays, and weekends=skip also leaves them out when counting durations in days and weeks. holidays= is a comma-separated list of days off that are shaded and not counted. Dates are YYYY-MM-DD.gantt "Launch plan" start=2026-01-05 unit=week today=2026-01-26 weekends=skip holidays=2026-04-03
section "<Name>" tone=<tone> {Opens a band of rows with its name in a tab on the left. Put tasks and milestones inside and close it with } on its own line. Sections do not nest. tone= colors the band and the bars inside it.section "Design" tone=violet {
task <id> "<Label>" start=<date> | after=<ids> duration=<n>d|<n>w|<n>mo | end=<date> status=<status> tone=<tone>A bar on the axis. Say when it starts with start= (a day) or after= (one or more ids, a comma-separated list: it starts the day after the last of them ends), and how long it lasts with duration= (days, weeks, or calendar months) or end= (its last day). status= is planned (the default), active, done, or critical, and critical can be added to another: status=critical,done. The label goes inside the bar when it fits and beside it when it does not.task ui "UI design" after=ux duration=2w status=active
milestone <id> "<Label>" at=<date> | after=<ids> status=<status> tone=<tone>A point in time drawn as a diamond: at= a day, or after= tasks, where the last of them ends. A milestone has no duration and no end. status= is planned, done, or critical.milestone beta "Beta" at=2026-03-02
desc "<text>"The plain-language description of the chart, for assistive technology; the same as desc= on the header.desc "A twelve week plan from research to launch."

Class diagram

Classes with their members and the relations between them, for object models. The header line is class "Title".

StatementWhat it doesExample
class <id> ["Label"] [type=<type>] [stereotype="<word>"] [tone=<tone>] [{]Declares a class, shown as a box. The label is the name in the header and may hold type parameters, such as "Repository". type is class (a concrete class. the default), abstract (a class that cannot be created itself, only extended), interface (a contract of methods that other classes implement), enum (a fixed set of named values; each member line is one value). Without a { the class has no members; with one, list them on the lines that follow and close with } on its own line.class Order "Order" type=class stereotype="entity" {
"<mark><name>[: <type>]" [static] [abstract]A member of the open class, one per line, the whole text in double quotes. The mark says who sees it: + public, - private, # protected, ~ package. A member with a parenthesis is a method and the rest are attributes; attributes are drawn first. After the colon comes the type. static draws it underlined and abstract in italics. On an enum, each member is one value."+place(order: Order): void" abstract
package <id> ["Label"] [tone=<tone>] {A frame around classes, with its name in a corner tab. Packages nest up to 3 deep. Close with } on its own line.package billing "Billing" tone=violet {
<from> ["<count>"] <relation> ["<count>"] <to> [: "label"]Relates two classes. The relation is one of: extends inheritance, implements realization, owns composition, has aggregation, -> association, <-> bidirectional, --> dependency, -- link. A count is the cardinality at that end, up to 12 characters, such as "1", "0..1" or "*". Write inheritance and implementation from the child to the parent, and composition and aggregation from the whole to the part.Customer "1" -> "*" Order : "places"
note on <class> : "text"A note card joined to a class by a dotted line. Write note : "text" for a note that stands alone.note on Order : "Totals are in cents."
desc "text"The plain-language description of the diagram, for readers who cannot see it. The header option desc="" does the same. direction=down|right|up|left on the header sets the reading direction; down, the default, puts parents above their children.desc "How an order reaches a customer."

State

States and the transitions between them, with composite states, choices, and parallel regions, for lifecycles and state machines. The header line is state "Title".

StatementWhat it doesExample
state <id> "Label" sub="<description>" tone=<tone> icon=<set:name>Adds one state: a rounded card with its name. sub= is the line or lines under the name, and a \n starts a new line. icon= puts a chip with that icon before the name, and a card with no icon has no chip. A tone other than neutral tints the card, and green, amber, or red also draw every transition that arrives at the state in a softer line of that tone, so the way to a good outcome and the way to a bad one part by color. The other tones never color a line. The ids start and end are taken by the markers.state paid "Paid" sub="Money received" tone=green
state <id> "Label" {Opens a composite state: a state that holds other states, drawn as a frame with its name, and its icon when it has one, in a corner tab. A frame inside a frame is shaded a step stronger. Close it with } on its own line. Inside, start and end are the markers of this state alone, and a transition may enter or leave the whole state by its id.state shipping "Shipping" {
from -> to : "event [guard] / action"Adds a transition. The label is optional, and each of its parts is optional too: the event that triggers it, a guard in square brackets that must hold, and an action after a slash that runs. The picture sets them apart: the event is plain text, the guard is a tag with a branch glyph, and the action follows a bolt glyph, so the brackets and the slash are not drawn. Only -> draws a transition. start and end are the markers of the scope the line is in: start only begins a transition and end only finishes one.pending -> paid : "payment received [card valid] / charge card"
start -> <id>The start marker of the scope: a filled dot where the lifecycle begins, at the top level of the diagram or inside a composite state. It needs no declaration.start -> pending
<id> -> endThe end marker of the scope: a ring with a dot, where the lifecycle finishes. It needs no declaration, and several transitions may lead to it.delivered -> end
choice <id> "Question?" tone=<tone> icon=<set:name>A pill where one path splits into several, each taken on a condition: a tinted pill with a branch icon in a round chip and the question beside it, a sibling of the state cards. icon= swaps the icon and icon=none leaves the chip out. The question is optional: with none the choice is a small circle holding only the icon, and its branches carry the conditions as guards. Its default tone is amber.choice stock "In stock?"
fork <id>A bar where one path splits into parallel paths. It grows long enough to hold the transitions that meet it.fork split
join <id>A bar where parallel paths merge into one.join merge
history <id> deep=onA circle marked H inside a composite state: entering it returns to the state that was active last. deep=on remembers the whole depth of the nesting and draws H*.history last deep=on
region "Name" {Opens a region inside a composite state: one of the parts that run side by side. A composite state with regions holds only regions, and each region has its own start and end markers. A dashed line separates the regions. The name is optional.region "Reader" {
note <id> : "text" side=<left|right|top|bottom>Attaches a note to a state, a choice, or a composite state. A note sits across the reading direction, so a transition never meets it: left and right become top and bottom in a diagram that reads sideways, and the other way round in one that reads up or down. A note on a composite state sits inside its frame. With no side, it goes below or to the right.note paid : "Refunds are allowed for 30 days" side=right
desc "<text>"A plain-language description of the diagram for the text description, as desc= on the header does.desc "How an order moves from payment to delivery."

Timeline

Dated events on a rail, in the order written and grouped in sections, for a history or a roadmap. The header line is timeline "Title".

StatementWhat it doesExample
timeline "Title" direction=right|down side=both|one desc="<text>"The header. direction=right (the default) draws a horizontal rail read left to right, direction=down a vertical one read top to bottom. side=both (the default) alternates the cards between the two sides of the rail, side=one puts them all on the same side: below the rail, or to its right. Periods are drawn in the order written, never sorted.timeline "Product history" direction=down side=one
section "Name" tone=<tone> icon=<ref> {Opens an era: a tinted frame, with its name in a corner tab, around the periods written before the closing } on its own line. A section takes the next tone of blue, violet, aqua, orange, green, amber unless tone= names another. Sections do not nest. A period written outside every section sits on the rail with no frame.section "Early days" tone=violet {
at "<period>" tone=<tone> : "<event>" sub="<text>" icon=<ref> tone=<tone>, "<event>"A period and its events on one line. The period is a milestone on the rail and each event is a card hung from it, the first nearest the rail. Events are separated by commas, and each may take sub= (a quieter second line), icon=, and tone=. A period is a label, not a date: "2019", "Q3 2019", "Spring", and "v2.0" all work. At least one event is expected; a period with none draws a milestone alone and a warning.at "2019" : "Founded", "First customer" sub="A design studio in Lyon" icon=lucide:flag
period "<period>" tone=<tone> {The same as at, with one event on each line, for a period whose events carry sub= and icon=. Write event lines inside it and close it with } on its own line.period "2020" tone=green {
event "<event>" sub="<text>" icon=<ref> tone=<tone>One card of the period block it is written in. Only a period block holds events; outside one the statement is error E381.event "Seed round" sub="Led by two angels" icon=lucide:wallet
desc "<text>"One or two sentences describing the timeline, for the text description. The same as desc= on the header.desc "How the product grew from a studio to a platform."

User journey

The steps a person takes and how they feel at each, as a satisfaction curve over stages of tasks and the actors involved. The header line is journey "Title".

StatementWhat it doesExample
journey "Title" desc="<text>" marks=faces|dots legend=on|offThe header. marks=faces (the default) draws a face from sad to happy on the curve, and marks=dots draws the score as a number in a dot. legend=off hides the legend of the scale and the actors. A journey may hold at most 100 tasks, 25 stages, and 24 actors, and a task may name at most 8 actors; past that it is refused with E140.journey "Checkout experience" desc="How a shopper feels from search to payment" marks=faces
section "Stage name" tone=<tone> {A stage of the journey: a named run of tasks, drawn as a frame with a tab, one after another from left to right. It needs at least one task. tone= tints the frame and is optional. Tasks written outside any section are drawn with no frame.section "Browse" {
task "Name" score=<1-5> actors="<Actor>, <Actor>" sub="<second line>"A step the person takes, with how they feel at it: score 1 is frustrated, 3 is neutral, and 5 is delighted. The score is a whole number and the only required option. actors= lists who is involved, separated by commas, each as a chip of initials; sub= adds a second line under the name. Tasks run left to right in the order written, and a smooth curve joins their scores.task "Find a product" score=5 actors="Customer"
actor "Name" tone=<tone>Declares an actor so its color is chosen, and so a task that names someone else is an error (a typo). It is optional: with no actor statement the actors are the names that the tasks use, in the order they appear. Without tone= an actor takes the next of blue, violet, neutral, aqua, orange, amber, green, red. Two spellings that differ only in case or spacing are one actor.actor "Customer" tone=blue
desc "text"One or two sentences describing the journey, for the text description. The same as desc= on the header.desc "A shopper finds a product, pays, and waits for the parcel."

Mind map

A root idea and the branches that grow from it, drawn round the root or as a tidy tree, for brainstorms and outlines. The header line is mindmap "Title".

StatementWhat it doesExample
mindmap "<title>" layout=<layout> desc="<text>"The header; title, layout=, and desc= are optional, and with no title the root names the picture. layout= is auto, radial, right, or down: auto draws radial when the map has two branches or more and fits a page column, and right otherwise; radial puts the root in the middle with its branches on both sides; right and down are tidy trees.mindmap "Product strategy" layout=radial
root "<label>" icon=<set:name> tone=<tone> shape=<shape>The central idea, written once, directly under the header. Every other topic branches from it. It is a circle in the ink colour unless it says otherwise.root "Product strategy" icon=lucide:target
topic "<label>" icon=<set:name> tone=<tone> shape=<shape>A branch of the root when written at the left margin, and of the topic whose block it sits in otherwise. Branches take blue, orange, aqua, violet, amber, green, and red in turn and keep the tone down the branch; tone= overrides it. shape= is pill, card, circle, or hexagon, and pill is the default. Topics have no ids.topic "Growth" tone=blue icon=lucide:users
topic "<label>" {A topic with branches of its own: end the line with {, write its topics on the lines after, and close with } on its own line. Blocks nest to 10 levels. Indentation means nothing.topic "Retention" {
}Closes the nearest block that is still open, on a line of its own.}

Treemap

Nested areas sized by value, grouped by branch, for where size or cost sits in a hierarchy. The header line is treemap "Title".

StatementWhat it doesExample
treemap "Title" unit="<unit>" sort=<desc|written> values=<on|off> better=<up|down> desc="<text>"The header. Every option is optional. unit= says what the values count and is drawn after each value (unit="MB", unit="%"; a currency symbol such as "$" leads). sort=desc (the default) draws the largest tile first, which packs best; sort=written keeps the order written. values=off hides the values on the tiles. better= says which way of a change is good news and so drawn green: better=up (the default) for sizes and coverage, better=down for cost and errors.treemap "Cloud spend" unit="$" better=down
group "<Name>" tone=<tone> icon=<icon> {Opens a frame sized by what it holds, with its name, icon, and total in a corner tab. Put items and groups inside and close it with } on its own line. Groups nest up to 4 deep. Each top-level branch takes the next tone of a rotation, and what is inside keeps it; tone= changes it. The theme chooses every color.group "Compute" tone=blue icon=lucide:server {
item "<Name>" <value> tone=<tone> icon=<icon> delta=<change>A tile whose area is its value. The value is a number above zero, written right after the name with no quotes and no unit. delta= draws a chip with an arrow and the size of a change since the last period, in the unit of the values or in percent: delta=5 for a rise, delta="-5" for a fall (a sign needs quotes), delta="-12%" for a percent. A tile too small for its label shows no label; the full list is in the text description.item "EC2" 12400 icon=lucide:server delta="8%"
desc "<text>"The plain-language description of the treemap, for assistive technology; the same as desc= on the header.desc "Where the monthly cloud bill goes, by service."

Share chart

Parts of a whole drawn as a donut with a legend, for a few shares that add up to one total. The header line is pie "Title".

StatementWhat it doesExample
pie "<title>" unit=<text> total=<text> sort=<order> values=<on|off> fold=<n> labels=<place> desc="<text>"The header; every option is optional. unit= is written after each number ("%", "ms", "visits") or before it for a currency sign ("$"). total= is the caption under the total in the hole of the ring (the default is Total). sort= is desc or written: desc draws the largest first, clockwise from the top, with Other last. values=off prints the share and not the number. fold=5 draws at most 5 slices and merges the smallest into one Other. labels= is outside or legend: outside names each slice beside the ring on a leader line, and legend names them all in a legend under it.pie "Where visits come from" unit=" visits" total="Visits" fold=5
slice "<name>" <number> tone=<tone> icon=<set:name>One share of the whole, written as its name and then its number: zero or more, plain digits with an optional fraction, no sign, comma, or percent sign. The ring scales the numbers to a full turn, so they need not add up to 100. Slices take blue, orange, aqua, violet, amber, green, red, and neutral in turn; tone= chooses one, and a slice named Other is grey. icon= puts an icon in the slice's label. Names are unique, in any case, and slices have no ids.slice "Search" 28 tone=aqua icon=lucide:search
desc "<text>"The plain-language description of the chart, for assistive technology; the same as desc= on the header.desc "Where the visits of one month came from."

Quadrant chart

Items placed on two axes and read by quadrant, for priorities such as impact against effort. The header line is quadrant "Title".

StatementWhat it doesExample
quadrant "Title" highlight=<zone> desc="<text>"The header. Both options are optional. highlight= names the zone to act on (top-right, top-left, bottom-left, or bottom-right) and gives it a stronger wash and an outline.quadrant "Where to invest" highlight=top-left
x "<Title>" low="<text>" high="<text>"The horizontal axis: low= is the word at the left end (the value 0) and high= the word at the right end (the value 1). With a title and no ends they read Low and High. Write at least one of the three.x "Effort" low="Easy" high="Hard"
y "<Title>" low="<text>" high="<text>"The vertical axis, the same way: low= is the bottom (0) and high= the top (1).y "Impact" low="Small" high="Large"
zone <position> "<Name>" tone=<tone> icon=<icon>Names one of the four zones in a tab in its corner. Position is top-right, top-left, bottom-left, or bottom-right. tone= washes the zone, and its points take that tone unless they choose their own.zone top-left "Quick wins" tone=green icon=lucide:zap
point "<Label>" x=<0 to 1> y=<0 to 1> tone=<tone> icon=<icon>An item. x runs across and y runs up, both from 0 to 1 (write 0.8, not 80). 0.5 is the dashed line and belongs to the high side. icon= draws a chip and no icon draws a dot. Labels are unique.point "Public API" x=0.7 y=0.8 icon=lucide:plug
desc "<text>"The plain-language description of the chart, for assistive technology; the same as desc= on the header.desc "Where each idea falls on effort and impact."

Layered architecture

Stacked layers of blocks with the links between them, for layered and tiered architectures. The header line is layers "Title".

StatementWhat it doesExample
layers "Title" direction=<down|up> counts=<on|off> desc="<text>"The header. Every option is optional. direction=down (the default) puts the first layer on top; direction=up puts it at the bottom, for a stack built on its foundation. counts=on shows how many blocks each layer holds in its tab.layers "Online banking" direction=down
layer "<Name>" tone=<tone> icon=<icon> {Opens a wide frame with its name in a corner tab. Write blocks inside and close it with } on its own line. Layers stack in the order written, up to 12. Each takes the next tone of a rotation unless tone= sets one, and its blocks keep the tone. The blocks share one row and wrap to more rows when they cannot keep their words whole. The theme chooses every color.layer "Domain" tone=violet icon=lucide:boxes {
block <id> "<Label>" sub="<note>" icon=<icon> tone=<tone> span=<1-6>A card in a layer or an aside. The id is what links name. sub= is a short note under the label, such as the technology. span= makes the card as wide as that many columns of its layer, so a database can be wider than a service. At most 80 blocks in all.block pay "Payments" sub="Go" icon=lucide:credit-card span=2
aside "<Name>" tone=<tone> icon=<icon> {A tall band beside the stack for what cuts across every layer, such as security or monitoring, with its own blocks stacked in it. Up to 2 asides. Blocks in an aside take no links, because the aside applies to every layer.aside "Security" icon=lucide:shield {
<from> -> <to> : "<label>"A link between two blocks of the layers. Arrows: -> a call, --> a reply or an optional link (dashed), <-> two ways, ..> asynchronous (dotted), -- no direction. The line leaves and enters the top and bottom of a block and never crosses a block. Keep the few links that show how the layers depend on each other.web -> pay : "REST"
desc "<text>"The plain-language description of the diagram, for assistive technology; the same as desc= on the header.desc "Each layer calls the layer below it."

C4 diagram

People, systems, containers, and components with their relationships and boundaries, in the C4 model of system context, container, component, deployment, and dynamic views. The header line is c4 "Title".

StatementWhat it doesExample
person|system|container|component|db <id> "Name" desc="<what it does>" tech="<technology>" external=on icon=<set:name> tone=<tone>Adds one element: a card with its name, a caption that says what it is ([Person], [Software System], [Container: Spring Boot]), and its description. person is a user, system a software system, container an application or a data store that runs on its own, component a part of a container, and db a database. tech= is the technology and shows in the caption. external=on marks a person or a system outside the scope of the picture: a plain card with a dashed outline, while everything inside the scope is tinted. Each type has its own icon and tone, and icon= and tone= replace them.container api "API Application" tech="Spring Boot" desc="Serves the banking data as JSON."
boundary <id> "Name" kind=system|container|enterprise|deployment|group tech="<technology>" {Opens a boundary: a frame with its name and a caption such as [Software System] in a corner tab, around the elements written inside it. Boundaries nest, up to four deep, and close with } on a line of its own. A deployment boundary is a solid frame with a server icon, and tech= is its technology, such as Ubuntu 22.04.boundary bank "Internet Banking System" kind=system {
from -> to : "What it does" tech="<protocol>"Adds a relationship between two elements. The label and tech= are both optional; the technology is a tag at the end of the label. -> is a call, --> an asynchronous or optional one (dashed), ..> an event (dotted), and <-> or <--> go both ways. In a view=dynamic diagram the lines are numbered in the order written.spa -> api : "Makes API calls to" tech="JSON/HTTPS"
desc "<text>"A plain-language description of the diagram for the text description, as desc= on the header does.desc "How the customer reaches the banking system."

Matrix

Rows against columns with meaningful cells, for options comparisons, decision matrices, RACI charts, and risk heat maps. The header line is matrix "Title".

StatementWhat it doesExample
matrix "Title" style=<style> total=<on|off> desc="<text>"The header. style= is compare (the default: options against criteria), score (a decision matrix, total on), raci (who is Responsible, Accountable, Consulted, Informed), or risk (a likelihood against impact grid). total=on adds a weighted total column.matrix "Message brokers" style=score
columns "<Name>" weight=<1 to 9> icon=<icon> "<Name>" "<Name>"The columns of compare, score, and raci: criteria, or roles in a RACI chart. Each quoted name may be followed by its own weight= (how much it counts in the total, default 1) and icon=.columns "Throughput" weight=3 icon=lucide:gauge "Ordering" "Cost"
row "<Name>" icon=<icon> tone=<tone> sub="<text>" : <cell>, <cell>A row with one cell for each column after the colon, separated by commas. A cell is yes, no, partial, na, a score from 0 to 5 (drawn as dots), or "quoted text". In style=raci a cell is R, A, C, I, a pair such as "A R", or na.row "Kafka" icon=simple:apachekafka sub="Log-based" : 5, yes, "Medium"
recommend "<Row name>"Marks one row as the pick, with a tone wash, a stronger outline, and a Recommended tab. It is never chosen from the totals for you.recommend "Kafka"
legend yes="<text>" partial="<text>" no="<text>" na="<text>"compare and score only: says what each mark means, drawn under the table as the same discs with their words. Only the marks named are shown, in the order written. Lint warns when a partial cell has no legend saying what partial means.legend yes="Allowed" partial="Own records only" no="Denied"
item "<Label>" likelihood=<1 to 5> impact=<1 to 5> icon=<icon>style=risk only: a risk placed on the 5 by 5 grid. The cell takes a band from likelihood times impact: low, moderate, high, or critical.item "Data loss" likelihood=2 impact=5 icon=lucide:database
levels <likelihood|impact> "<L1>" "<L2>" "<L3>" "<L4>" "<L5>" title="<text>"style=risk only: names the five levels of an axis, lowest first, and optionally the axis. Without it the levels run Rare to Almost certain and Negligible to Severe.levels likelihood "Rare" "Unlikely" "Possible" "Likely" "Certain"
desc "<text>"The plain-language description of the matrix, for assistive technology; the same as desc= on the header.desc "Four brokers scored on five criteria."

Sankey diagram

Flows between stages drawn as ribbons as thick as the amount, for where traffic, data, or cost goes. The header line is sankey "Title".

StatementWhat it doesExample
sankey "<title>" unit="<unit>" values=<on|off> sort=<desc|written> align=<justify|left> desc="<text>"The header; every option is optional. unit= says what the amounts count and is written after each amount (unit="req/s"), or before it for a currency sign (unit="$"). values=off hides the amounts. sort= is desc or written: it orders the first column and settles ties. align= is justify or left: justify puts every node with nothing leaving it in the last column, left leaves it beside its source.sankey "Request traffic" unit="req/s"
"<From>" -> "<To>" : <amount> tone=<tone>One flow, written as the two node names, an arrow, a colon, and the amount: plain digits with an optional fraction, above zero, no sign, comma, or unit. A node exists once a flow names it, so a node has no id and its name is its identity. The ribbon is as thick as the amount and takes the tone of the node it leaves. The same pair is written once. A flow back to an earlier node is an error, because a sankey only goes forward. Nodes take blue, orange, aqua, violet, amber, green, and neutral in turn, in the order they first appear."Edge" -> "API gateway" : 12000
node "<Name>" icon=<set:name> tone=<tone>Gives a node an icon and a tone. Write it before or after the flows that name the node, once. A node line for a name no flow uses is an error. The theme chooses every color.node "API gateway" icon=lucide:server tone=blue
desc "<text>"The plain-language description of the diagram, for assistive technology; the same as desc= on the header.desc "How requests move from the edge to the data stores."

XY chart

Bars, lines, and areas over a category or number axis, with reference lines, for metrics, capacity, and trends. The header line is xychart "Title".

StatementWhat it doesExample
xychart "<title>" direction=<vertical|horizontal> stack=<on|off> values=<on|off> desc="<text>"The header; every option is optional. horizontal puts the places down the side, which suits a ranking. stack=on stacks the bar series. values=off leaves the numbers off the bars. The title is in a corner tab.xychart "Latency by week" stack=off
x "<title>" ["<place>" "<place>"] or x "<title>" <from> to <to>The horizontal axis, once: named places in square brackets, or a number range that every series is spread evenly over. Each series then has one value for each place. Write a negative number as -5, and text with + ( < # or a bare / in quotes.x "Week" ["W1" "W2" "W3" "W4"]
y "<title>" unit=<text> min=<number> max=<number>The value axis, once; every part is optional. Ticks are on round numbers. Bars and areas start at zero unless min= says otherwise (lint warns). A word unit such as "ms" goes in the title, a symbol such as "$" or "%" on the numbers.y "Latency" unit="ms" min=0 max=800
bar|line|area "<name>" [<number> <number>] tone=<tone> icon=<set:name>One series: its name, then one plain number for each place in square brackets. area adds a wash under its line. Series take blue, orange, aqua, violet, amber, green, red, and neutral in turn; tone= chooses one. Up to 4 series are named beside their last points, more in a legend.line "p95" [310 360 345 420]
threshold "<label>" <number> tone=<tone> breach=<above|below|none>A labelled reference line, red unless tone= says otherwise. A bar or point on the wrong side of it (above by default) is drawn in its tone. The axis grows to hold it.threshold "SLO 400 ms" 400 tone=red
note "<text>" at="<place>"A callout above the plot with a dotted line down to a place on the x axis (an x value on a number axis). Not on a horizontal chart.note "Release 2.3" at="W3"
desc "<text>"The plain-language description, for assistive technology; the same as desc= on the header.desc "How the latency of the API moved over eight weeks."

Tree

A hierarchy drawn as a file tree, an org chart, or an outline, for repository layouts, teams, ownership, and taxonomies. The header line is tree "Title".

StatementWhat it doesExample
tree "Title" style=<files|org|outline> direction=<down|right> counts=<on|off> desc="<text>"The header. style=files (the default) draws a repository layout: a rounded frame with the title in its corner tab, one row for each entry with an icon chip, the name, a quiet column of notes, and thin guide lines from a folder to its entries. style=org draws cards in a tidy tree, for teams, ownership, and service dependencies: direction=down (the default) or direction=right says which way it grows, and a wide chart lists leaves under their parent. style=outline draws a compact bulleted list for a taxonomy. counts=on adds how many entries each folder holds. Only org reads direction.tree "plotwork-app" style=files
dir "<Name>" note="<text>" icon=<icon> tone=<tone> change=<added|modified|removed> size="<size>" mark=<on|off> {A folder, a team, or a group. Write its entries inside and close with } on its own line; with no { it is an empty or collapsed folder. Entries nest up to 8 levels. note= is the quiet text after the name, or the second line of a card. change= washes the row green, amber, or red with a chip, for a diff. size="12 KB" is a pill at the right of the row. mark=on emphasises the entry. The folder icon is the default; tone= tints it.dir "src" note="source code" icon=lucide:folder {
file "<name>" note="<text>" icon=<icon> tone=<tone> change=<added|modified|removed> size="<size>" mark=<on|off>A file, which holds nothing. Its icon is chosen from the name: TypeScript, JavaScript, JSON, Markdown, CSS, HTML, YAML, TOML, lock files, images, shell, Python, Go, Rust, Java, SQL, Dockerfile, and .gitignore each get one, and any other name gets a plain file icon. icon= overrides it. A name with a dot or a slash needs its quotes, as every name does.file "main.ts" note="entry point" change=modified size="2 KB"
node "<Name>" note="<text>" icon=<icon> tone=<tone> change=<added|modified|removed> size="<size>" mark=<on|off> {A person, a team, a service, or a topic, for org and outline trees. It has no id, because a tree has no cross references. Write its reports or dependencies inside { }, or leave the braces off for a leaf.node "Platform" note="12 engineers" icon=lucide:users {
omitted <count> "<noun>"A quiet entry that says how many more exist and are not drawn: omitted 14 "files" draws "and 14 more files". Use it to keep a large folder short.omitted 14 "files"
desc "<text>"The plain-language description of the tree, for assistive technology; the same as desc= on the header.desc "The layout of the repository."

Swimlane

A process whose steps sit in lanes, one for each actor or system, with decisions and hand-offs between the lanes, for business and integration flows. The header line is swimlane "Title".

StatementWhat it doesExample
swimlane "Title" direction=<auto|right|down> numbered=on start=<n> desc="<text>"The header. right draws the lanes as bands with time running left to right, down draws them as columns with time running down, and auto (the default) keeps the bands unless they would be wider than a Markdown column. numbered=on draws a numbered badge on each transition in the order written, and start= sets the first number.swimlane "Order fulfilment" direction=right numbered=on
lane <id> "Name" tone=<tone> icon=<set:name> {Opens a lane: the actor or system that performs the steps written inside it, drawn as a band or a column with its icon and name in a rail at its start. Lanes stack in the order written. Close it with } on its own line. Every step belongs to a lane.lane customer "Customer" icon=lucide:user {
step <id> "Label" sub="<detail>" tone=<tone> icon=<set:name>A step, drawn as a card in its lane. sub= is the line under the name, and a \n starts a new line. A tone other than neutral tints the card, and green, amber, or red also draw every transition that arrives at it in a softer line of that tone.step charge "Charge card" sub="Payments service" icon=lucide:credit-card
decision <id> "Question?" tone=<tone> icon=<set:name>A decision, drawn as a tinted pill with a branch icon: one way in, and a transition out for each answer, each labelled with the condition that takes it. The default tone is amber.decision stock "In stock?"
start <id> "Label" tone=<tone> icon=<set:name>Where the process begins, drawn as a small pill.start received "Order received"
end <id> "Label" tone=<tone> icon=<set:name>Where the process finishes, drawn as a small pill. A process may have several ends, such as delivered and cancelled, and a green, amber, or red one colors the line that reaches it.end delivered "Delivered" tone=green icon=status:success
from -> to : "event [guard] / action" step=<n>A transition, which may cross lanes freely and may return to an earlier step. The label and each part of it are optional: the event, a guard in square brackets that must hold, and an action after a slash. --> draws a dashed line, for a reply or an asynchronous hand-off, and ..> a dotted one, for an event. step= sets or skips the badge of a numbered diagram.stock -> charge : "[in stock]"
desc "<text>"A plain-language description of the process for the text description, as desc= on the header does.desc "How an order moves from the shop to the customer."

Tones and settings

SettingValues
Tonesneutral, blue, violet, aqua, orange, green, amber, red
Flow directions (direction=)auto, right, down, left, up
Themeslight, dark
Sequence framesalt, opt, loop, par
Schema column flagspk, fk, unique, nullable

See also

DocWhy
Language referenceEvery page of the reference and what each covers
Writing diagramsThe language by example, kind by kind
Flow node typesThe types a flow node can take
Diagnostic codesWhat every error and warning means