skill
squinch
A skill for AI coding agents that draws clean, professional architecture diagrams as code: real cloud icons, zoomable from the landscape down to one service, exported as SVG, PNG or interactive HTML.
Set up
Skills are installed by placing their folder where your agent loads skills.
The download comes from github.com/jquatier/squinch itself, not from our server, so what you get is exactly what its author published.
Install instructions come from the README
README
synced Oct 26, 2026squinch
squinch (n.) — the corner arch that lets a round dome sit on a square room; the piece of architecture that makes mismatched structures fit together.
Your AI coding agent already knows the architecture — now it can draw it. Squinch is a skill for AI coding agents: describe the system in a paragraph and the agent writes a small, readable model that renders as a clean, professional diagram — real cloud icons, layout you steer without placing a box, and altitudes you can zoom through, from the whole landscape down to one service's internals.
Quickstart
npm i -g squinch # or npx squinch <cmd>
squinch skill # teach your agent the language
Then ask for a diagram in plain language. The agent does the rest — writes the model, checks it, fixes what the checker flags, and renders it as SVG, PNG or the interactive HTML you can zoom through. Works with any agent; details and the other surfaces are in Install.
From description to diagram
Hand your coding agent the bundled
skill and describe the system in a paragraph. It writes the
.squinch model, squinch check tells it what is wrong in terms it can act on,
and squinch render produces the diagram as SVG, PNG or interactive HTML —
deterministic, reviewable in a pull request, and living in git beside the code
it describes. The diagram above is
examples/products-api; its source is
further down this page, and CI holds the two
together.
Zoom into any system
C4-style zoom, from one model. The altitudes are derived, never drawn twice: a collapsed system is a card previewing what is inside; opening it shows the internals while the neighbours it talks to stay on screen as muted context; and edges that crossed the boundary re-anchor themselves, aggregating behind a count badge when several collapse into one. Nothing is duplicated, so nothing can drift — see examples/microservices for the source.
Features
- LLMs write it fluently. Give your coding agent the bundled skill and ask for a diagram of your system. The language was designed for agents to author rather than retrofitted for them, so what comes back is a correct diagram, not one you have to redraw.
- 1,358 real vendor icons. AWS, Azure, Google Cloud, Kubernetes and product logos, not grey boxes with labels on them.
- Auto-layout that gets it right, and lets you overrule it. Good diagrams
with no hints at all; when you disagree, steer it with
rows,place right-of,alignand explicit edge routing — relative hints, never pixel coordinates. - Many diagrams from one description. A landscape view, a per-service view,
a filtered view for an audit — all from the same source, so they cannot
disagree with each other. Tag things
#pciand get a view that dims everything else. - Click into any system. C4-style altitudes from a single model, so there's no second diagram to keep in sync.
- Deployment boundaries drawn properly. VPCs, subnets, cloud and on-prem zones — nested, tinted by kind, with the boundary label straddling the border where you expect it.
- Trace a request through the system. Declare a flow and its steps are numbered along the edges in order — and in the interactive export you can walk it one hop at a time.
- Exports to SVG, PNG, or one interactive HTML file. SVG drops straight into a README (including a single file that follows the reader's light or dark mode); the HTML carries every view with click-to-zoom and presentation mode, and needs no server, no internet and nothing installed by whoever you send it to.
- A real VS Code extension. Autocomplete, live errors with one-click fixes, and a preview that updates as you type.
- Reviewable in a pull request. The source is a handful of readable lines,
so a reviewer sees the change itself — and
squinch diffspells it out: "edge added: checkout → fraud", not a thousand lines of changed path data. - Generated in CI, source kept in git. The
.squinchfile lives next to the code it describes, and a ready-made GitHub Action re-renders on every push — failing the build when a committed diagram has drifted, so the picture in your README is never stale. - Light and dark. Dark is designed, not inverted — and one
--adaptivefile can carry both, switching with the reader'sprefers-color-scheme.
Install
The agent skill is the front door — one command, then ask your agent for a diagram:
npx squinch skill
That writes .agents/skills/ in your project (plus .claude/skills/ when it
detects Claude Code); --global does the same under your home directory, and
--print emits the skill — SKILL.md and its references/ — as one stream
for any other harness. macOS, Linux and Windows, on
Node ≥ 22.
The other surfaces, each its own one-liner:
- The CLI —
npm i -g squinch(or run everything throughnpx squinch <cmd>), and the first render is two commands:squinch init my-diagrams, thensquinch render my-diagrams --sync. Once a day it asks the npm registry whether a newer version exists and says so on stderr after a successful command (and tells you when the installed skill was written by a different squinch);SQUINCH_NO_UPDATE_CHECK=1turns both off, andCIalready does. - The Claude Code plugin — the same skill without touching your repo:
/plugin marketplace add jquatier/squinch, then/plugin install squinch@squinch. Updates arrive with the plugin instead of living in your tree. - The Codex plugin — the same directory, packaged as an
Agent Plugin:
codex plugin marketplace add jquatier/squinch, thencodex plugin add squinch@squinch. Cursor, Copilot and Kiro read the same manifest. - The VS Code extension — download
squinch-vscode-<version>.vsixfrom Releases andcode --install-extensionit. The same file installs in Cursor, Windsurf and VSCodium. - CI —
uses: jquatier/squinch/.github/actions/squinch-check@mainfails the build when a committed SVG is stale;squinch-diffcomments what changed, architecturally, on the PR. Pin theversioninput: rendering is deterministic per tool version, so a floatinglatestcan change your goldens on someone else's release day. A path can be a single file or a directory — a directory is one project, and its files share a namespace.
| Command | |
|---|---|
check | parse + lint; --format json for agents |
render | --view, --theme, --adaptive, --sync, --check; -o out.png rasterizes (--scale, --width, --background), -o out.html exports the interactive viewer |
diff | semantic model diff — --base <ref>, --format markdown, --fail-on structural|any for CI |
icons search | find an icon id across installed packs |
init | scaffold a starter project |
skill | install the agent skill |
watch | re-render on change |
From source to diagram
The whole file — structure first, then a separate view that says how to draw
it. No coordinates anywhere: the boundary says what is inside the VPC, and the
layout falls out of the graph.
// A products API on AWS: edge, a service in a VPC, a self-warming index.
pack aws
person shopper "Shopper"
cdn = aws/cloudfront "CloudFront" { subtitle: "edge cache" }
alb = aws/elb "Application Load Balancer" { subtitle: "internet-facing" }
app = aws/fargate "Products API" {
subtitle: "Fargate · ECS"
description: "ECS on Fargate, private subnets across two AZs"
}
db = aws/dynamodb "Products Table" datastore {
subtitle: "DynamoDB · on-demand"
description: "Single-table design, on-demand capacity"
}
indexer = aws/lambda "Stream Indexer" { subtitle: "Lambda · Node 20" }
search = aws/opensearch "Search Index" datastore { subtitle: "OpenSearch 2.x" }
shopper -> cdn "api.example.com"
cdn -> alb "/products/*"
alb -> app
app -> db "read / write"
app -> search "search products"
// A stream needs a consumer — this is what keeps the index in step.
db ~> indexer "DynamoDB stream"
indexer -> search "index updates"
zone vpc "VPC prod-main" vpc {
contains alb, app
icon: aws/vpc
label: bottom-right // clear of the edge arriving at the top
}
view products {
title "Products API — edge to index"
legend auto
layout {
// `alb` names the VPC's rank — one member is enough to place a zone.
rows [shopper cdn] [alb] [db indexer search]
}
}
Why
Auto-layout tools give you no recourse when the picture comes out wrong: add a node and everything reshuffles, edges cross, and your only option is to accept it. Manual tools give you control but an un-diffable file. Squinch takes the third path — excellent auto-layout by default, plus relative hints (never pixel coordinates) that both humans and LLMs can reason about:
rows [api] [create get search]— pin ranks and their orderplace sync right-of db— relative placement, no geometryalign get db— put two nodes on a shared axisroute db ~> sync from east to west— pick the sides an edge leaves and enters
Three tiers, in the order you reach for them: auto-layout underneath, relative
placement on top of it (rows, cols, place, align), explicit edge routing
last (route, channel). A system can carry its own layout { } for its interior,
and that arrangement follows it into every view that opens it. Delete every hint and
the diagram still renders well.
Hints that contradict each other are check-time errors, never silently dropped — a dropped hint strands the agent loop, a named conflict gets fixed in one iteration:
conflict.squinch:9:5 error: contradictory place hints: `s.a` vs `s.b` reference each other
remove one of the two place statements
What it can draw
Every picture below is a committed render from lookbook/, rebuilt and byte-compared on every push — so none of them can quietly stop being true.
Also in the language: cols to pin the other axis, datastore / external
node kinds, descriptions, and container nesting. Async edges (~>) are dashed
and animate at a constant speed — CSS keyframes, never script. Full grammar in
docs/SPEC.md.
Written by agents, and tested that way
The claim on the tin is that an LLM can write this fluently. That is a testable claim, so it gets tested.
Errors are built for the agent loop, not just for humans: every diagnostic
carries a location, the problem, and a likely fix, with did-you-mean suggestions
for unknown icons, views and identifiers. squinch check --format json emits
exactly the same information a person sees.
SKILL.md, with the references/
beside it, is the whole contract an
agent needs — npx squinch skill installs it for every skills-compatible agent
(or paste it into whatever your harness calls context), then ask for a diagram
in plain language; the package README has the details.
The gauntlet is the acceptance test: thirty-eight architecture prompts — thirty-seven in plain language and one that hands the agent a real repository — each solved cold by a fresh agent given only SKILL.md and the CLI — no examples, no human layout fixes, no coaching. A deterministic scorer checks the structure, icons, tags and views of every solution, and CI regression-tests the whole corpus on every push.
The agents are kept genuinely cold, and physically so: each one runs in a
sandbox holding nothing but SKILL.md, its prompt and a squinch binary (and,
for the repository prompt, that repository at a pinned commit), with
this repository unreachable from inside — no examples, no docs, no engine
source, and no previous answers to copy. Every prompt is re-run from scratch as
the language grows, and the bar rises with it — the corpus has gone
10 → 16 → 20 → 29 → 33 → 35 → 37 → 38 prompts as zones, flows, tag lenses,
channels, more packs, the positional-tag grammar, large-system prompts,
database tables and a real repository landed.
The committed corpus scores 38/38 with zero human layout fixes. Every round is written up in gauntlet/README.md — what was asked, how it was run, and what came back.
Deterministic by construction
The same source, packs, and theme always produce byte-identical SVG — text is measured from a bundled metrics table, never from the environment, and CI byte-compares the goldens on macOS, Linux and Windows, so the guarantee holds across platforms and not just across runs. That makes committed renders a workflow rather than a liability:
squinch render diagrams/ --sync # write SVGs for every view × theme, each stamped with the version that drew it
squinch render diagrams/ --check # CI gate: fail if a committed SVG is stale
Commit the source and the render. Reviewers see the picture in the diff; CI makes
sure it never drifts from the source. Every SVG names the squinch that drew it
(data-squinch on the root), so a stale render always says which version to
compare against; --check compares the picture and ignores the stamp, so a tool
upgrade only fails it when the picture actually changed. (Add
.github/actions/squinch-check to your workflow to enforce it.)
And when the picture changes, squinch diff says what changed in the
architecture's own vocabulary, not in path data:
$ squinch diff diagrams/ --base main
structural
+ node cache "Hot Cache" (aws/elasticache)
+ edge app -> cache "session reads"
2 structural, 0 cosmetic
Structural changes are new boxes and arrows; cosmetic ones are labels,
descriptions and styling. --format json | markdown and
--fail-on structural are built in, so a PR comment or a "no architecture
changes slipped in" gate is one CLI call, not a parser.
One file that follows the reader's theme
Embedding a diagram somewhere you don't control the background — a docs site, a
wiki, an internal portal — usually means shipping two files and a <picture>.
--adaptive folds both palettes into one SVG and lets prefers-color-scheme
pick:
squinch render diagrams/ --view landscape --adaptive -o architecture.svg
The light theme stays in the presentation attributes and the dark one rides in a
@media block, so anything that ignores CSS — including the resvg rasterizer
behind PNG export — still draws the light theme correctly rather than nothing.
It costs under 2% over a single render, versus two whole files. Still no
script: a stylesheet is not code.
Themes
Two, and dark is designed rather than inverted — not a palette flipped through a filter. The same two nodes, both ways:
--adaptive folds the pair into one file behind prefers-color-scheme, so an
embedded diagram follows the reader's OS without you picking a side.
The lookbook renders 35 deliberately awkward cases — dense meshes, long labels, deep nesting, coplanar rows — to 86 committed SVGs across the themes, and CI fails if any of them changes unintentionally.
Icons
1,358 marks across six packs, five chosen because they can be redistributed and one shipped on Google's stated purpose for it:
| Pack | Count | Terms |
|---|---|---|
pack-aws | 316 | CC-BY-ND 2.0 — the same basis AWS uses for its own PlantUML icons |
pack-azure | 636 | Microsoft's icon terms: copy and distribute for architecture diagrams, training and documentation |
pack-logos | 147 | CC0, from Simple Icons — the non-cloud half of a stack |
pack-sys | 195 | ISC, from Lucide — the generic set: servers, hardware, network gear, shapes, data/ML and commerce concepts |
pack-k8s | 39 | Apache-2.0 / CC-BY-4.0 — the official Kubernetes community icons, published to standardize cluster diagrams |
pack-gcp | 45 | Google's icon library, published "for your diagrams, technical documentation, and more" — no redistribution grant; see its NOTICE for the footing |
$ squinch icons search factory
azure/data-factories
sys/factory (or sys/onprem, sys/plant)
Aliases collapse onto the canonical id, so the word you reach for usually works
— gear, cube, db, rack, firewall, vault, cron all land somewhere
sensible. sys/* is the generic half, for everything no cloud vendor draws. A
pack statement is optional for every installed pack — it validates the name
at check time and documents what the file draws from, but nothing gates on it;
it becomes load-bearing when local packs (pack corp from "./icons") land.
Two constraints travel to you, not just to us. The cloud artwork must not be
modified — not recoloured, not reshaped, not run through an SVG optimizer;
Squinch applies all theme treatment at render time and never touches the asset.
And Azure's grant is narrower than an open-source licence: it covers
architecture diagrams, training and documentation, and does not travel to other
uses. Lucide's ISC and Simple Icons' CC0 carry no such limits, though those are
shipped verbatim too so npm run fetch can pick up upstream fixes without
re-applying local edits. Each pack's NOTICE has the details.
Google Cloud is the exception to "chosen because they can be redistributed".
Google publishes its icons for diagrams and documentation and says nothing
about redistributing them; draw.io, diagrams, Iconify and the PlantUML sprite
libraries have shipped them for years without objection, and pack-gcp stands
on the same footing, stated in full in its NOTICE. It ships Google's current
icon system — 19 core-product marks and 26 category glyphs, every other product
resolving to its category's glyph by Google's own design — and not the 216
legacy per-service icons, which Google says "should not be used as of 2026".
Editor support and a playground
The VS Code extension is a real language server — completions that know which block you're in, live diagnostics with quick fixes, hover, document symbols, and a preview pane that re-renders as you type.
The playground is the app in the zoom animation above: click a system to
dive into it, walk a flow one hop at a time, ⌘K to search 1,358 icons, and
full-screen the declared views as a presentation deck. It lives at
squinch.cc/playground — nothing you draw
leaves your browser — or run it locally with pnpm --filter @squinch/spa dev.
And that zooming travels. render -o diagram.html writes one self-contained
file carrying every view, both palettes and the viewer itself — click into a
system, walk a flow, present it full-screen, all from a file you can email or
drop on a static host:
squinch render diagrams/ -o architecture.html
It fetches nothing, and the entry view is inline, so a reader with JavaScript
disabled still sees a diagram. That export is the one artifact allowed to
carry a script, and it is a separate class rather than a loophole: the SVGs
inside it are byte-for-byte what render -o x.svg produces, the viewer is
their sibling and never their content, and a test asserts nothing executable
survives removing the two <script> elements
(docs/notes/html-export.md). Exported .svg never
contains script, full stop.
Docs
- DSL specification (v0 draft)
- Design language
- Engineering constraints — performance budgets, verification, and what is deliberately not built
- Engineering notes — decisions with their rejected alternatives
- Examples and the lookbook
- Contributing · Security policy · Icon notices
Acknowledgments
Squinch's model/view approach builds on the ideas of the C4 model for visualizing software architecture.
License
Squinch itself is Apache-2.0. The bundled icon artwork is not — each pack is redistributed verbatim under its own terms, and that credit travels with anything that serves the artwork (the playground carries it under "icon credits"):
| Pack | Attribution | Terms |
|---|---|---|
pack-aws | Amazon Web Services — AWS Architecture Icons | CC-BY-ND 2.0 — attribution required, no derivatives |
pack-azure | Microsoft — Azure Architecture Icons | Microsoft's icon terms — architecture diagrams, training and documentation only |
pack-k8s | © the Kubernetes Authors — community icons | Apache-2.0 or CC-BY-4.0 — attribution required |
pack-gcp | Google — Google Cloud icon library | No published grant — architecture diagrams and documentation, the purpose Google publishes them for |
pack-logos | Simple Icons | CC0-1.0 — the marks remain their owners' trademarks |
pack-sys | Lucide, portions from Feather | ISC (Feather portions MIT) |
Kubernetes and the Kubernetes logo are trademarks of The Linux Foundation;
Google Cloud and its product names are trademarks of Google LLC; brand marks
in pack-logos belong to their respective owners. Use throughout
is nominative — identifying the thing a diagram depicts — and implies no
endorsement or affiliation. Each pack's NOTICE carries the full text and
records the fetch-time treatments applied.