quad

quad is a language for drawing tidy flow diagrams where boxes line up cleanly, gaps come out even, and everything is forced onto an invisible grid.

The compiler and every example on this page are in the quad repository.

Diagrams rot. You add one box and spend ten minutes dragging the others around. You hand the file to a graph layout tool and everything jumps. Labels of different lengths give you boxes of different widths. Arrows come out almost straight. Gaps come out almost even.

quad puts everything on a grid. One box size, one gap, integer coordinates from the first statement to the last line of SVG. Every label is measured with the real font, so a longer one does not make a wider box.

diagram "Release" { flow down }

kind stage box spans [1, 2]

stage  build  "Build"
stage  test   "Run tests"
choice green  "All green?"
stage  sign   "Sign artifacts"
stage  notify "Notify author"
end    ship   "Publish release"

build -> test -> green
green -> sign : yes
green -> notify : no
sign -> ship
notify -> ship

sameline build test green sign ship
order green: sign notify
role error { notify, green -> notify }
A release pipeline, the main path straight down the page and a red branch to one side
A release pipeline.

box, choice and end draw the shapes. -> draws an arrow, and a word after a colon labels it. sameline keeps the main path straight. role error marks the branch that goes wrong; the color for it lives in a theme file.

quad doesn't do very much

quad isn't a drawing program and it won't lay out an arbitrary graph. Hand it an ugly mess and you get an ugly mess. It draws flow diagrams: things that happen in an order, with branches, sometimes in lanes. If that's not what you have, use Graphviz.

There's no editor, no live preview and no web playground. You write a file and run a compiler.

No coordinates, anywhere

There are no coordinates anywhere in the language. samestep puts boxes in the same step. apart says how far apart two of them sit. between puts a box in the middle of others. Turn the whole thing sideways with flow right and they all still hold.

Two parallel chains of three boxes between a start and an end box with sameline pb eb sb
Two parallel chains of three boxes between a start and an end box, drawn without that line without it
Two chains that never touch. Delete the line naming the second one and it bends around the first.
io  ingest "Ingest"
box pa "Parse A"
box ea "Enrich A"
box sa "Score A"
box pb "Parse B"
box eb "Enrich B"
box sb "Score B"
end merge "Merge"
ingest -> pa -> ea -> sa -> merge
ingest -> pb -> eb -> sb -> merge
sameline pa ea sa
sameline pb eb sb
apart pa pb: 2 lines
between pa pb: ingest
between pa pb: merge

Lanes and groups

lane puts a band behind the boxes belonging to one person, team or service. group draws a region around a set of boxes and moves them as one. A group can run in its own direction, so a diagram going down the page can hold a row going across it.

An incident review drawn across three swimlanes
Lanes for who does what, every shape the language draws, an arrow back onto the box it left, and a branch marked as the one that goes wrong.
diagram "Incident review" { flow down }

io     page    "Page on call"
box    triage  "Triage"
choice sev     "Severity?"
box    mitigate "Mitigate"
box    escalate "Escalate"
box    verify  "Verify fix"
box    postmortem "Write postmortem"
end    closed  "Closed"

note   runbook "Runbook"
mark   clock   "SLA clock"
box    timeline "Timeline"

page -> triage -> sev
sev -> mitigate : low
sev -> escalate : high
mitigate -> verify
escalate -> verify
verify -> postmortem -> closed
triage -> runbook
runbook -> clock -> timeline
mitigate -> mitigate : retry

sameline page triage sev mitigate verify postmortem closed
samestep mitigate escalate
sameline runbook clock timeline
order sev: mitigate escalate

lane oncall  "On call"  { page triage sev mitigate verify postmortem closed }
lane manager "Manager"  { escalate }
lane records "Records"  { runbook clock timeline }

role error { escalate, sev -> escalate }
A checkout flow across three swimlanes, with a dashed recovery group running left to right
The recovery steps are a group running left to right inside a diagram running down.
diagram "Checkout" {
  flow down
}

box place     "Place order"
box validate  "Validate order"
box authorize "Authorize card"
box ship      "Ship"
end confirm   "Confirm to buyer"

box log       "Log failure"
box notify    "Notify buyer"
box hold      "Hold order"

place -> validate -> authorize
authorize -> ship : approved
authorize -> recovery : declined
ship -> confirm
log -> notify -> hold

group recovery "Recovery" { flow right; log notify hold }

lane customer "Customer" { place confirm }
lane system   "System"   { validate ship recovery }
lane bank     "Bank"     { authorize }

role error { recovery, authorize -> recovery }

Themes

A theme is a file of colors, fonts and line widths. You pass it with --theme. Anything it leaves out keeps the built-in value, so a theme can be three lines.

A theme also says how sharply an arrow turns. corners is how much of each corner an arrow keeps, from 100 down to 0. 100 keeps the whole corner, so the arrow turns at a right angle. 50 keeps half of it, so the arrow curves with a straight run either side. 0 leaves no straight run.

A start box, a decision, a branch that recovers, and both paths meeting at an end box, drawn against square.toml square.toml
# A theme keeping the whole of every corner, so an arrow turns at a
# right angle.

[style]
corners = 100
A start box, a decision, a branch that recovers, and both paths meeting at an end box, drawn against halfway.toml halfway.toml
# A theme keeping half of each corner, so a curve has a straight run
# either side of it.

[style]
corners = 50
The same diagram under two themes. The diagram file says nothing about corners.
box    start    "Start"
choice ok       "OK?"
box    carry_on "Carry on"
box    recover  "Recover"
end    done     "Done"
start -> ok
ok -> carry_on : yes
ok -> recover : no
carry_on -> done
recover -> done

Related work

All of these are older, better documented and more capable than quad, and quad took something from every one of them.

Get it

Building quadc needs Rust 1.80 or later. On macOS Homebrew installs it; elsewhere rustup does, with one command on Linux and an installer on Windows.

# macOS
brew install rust

# Linux
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
git clone https://github.com/thomergil/quad.git && cd quad
cargo build --release
./target/release/quadc build diagram.quad -o diagram.svg

Draw one with Claude

This repository is a Claude Code plugin marketplace.

cargo install --git https://github.com/thomergil/quad quadc
claude plugin marketplace add thomergil/quad
claude plugin install quad@quad

The skill is /quad:draw.

Read on

Back to top