Skip to content
docspp

Open source · MIT · Astro and Starlight

Architecture diagrams you canpress playon.

Describe your system in YAML. docspp lays it out, documents every box, and replays a request travelling through it, one step at a time. Readers see how it works instead of guessing.

Get startedOpen playground
$npm create docspp@latest my-docs
checkout12 nodes · 4 scenarios · 2 viewsThe real thing, not a screenshot. Click a box, or hold Ctrl or ⌘ and scroll to zoom.

Everything in one picture. Letters on the edges match the interfaces table underneath.

Scenario

The shopper pays. The order is stored first, charged second, and announced to the rest of the system last.

HTTP request / responseData accessPersistent channel (websocket, gRPC)Queue / brokerDashed: planned
Loading diagram…
ISubmit
1
Shopper browser→order-servicevia CDN, API gatewayPOST /orders

The gateway has already checked the token, so the order service trusts the user id header.

2
order-service→PostgreSQLINSERT order (pending)
IICharge
3
order-service→Stripecreate payment intent
4
Stripeauthorise card
5
Stripe→order-servicesucceeded
IIIFinish
6
order-service→PostgreSQLmark paid
7
order-service→RabbitMQorder.created
8
order-service→Shopper browservia API gateway, CDN201 Created
9
RabbitMQ→notification-workerorder.createdplanned

Planned. Confirmation emails are not sent yet.

KeyFrom → ToKindAuthWhat travels
AShopper browser → CDNhttp—HTTPS
BCDN → API gatewayhttp——
CAPI gateway → Keycloakdataclient credentialssigning keys
DAPI gateway → catalog-servicehttp—/products
EAPI gateway → cart-servicehttp—/cart
FAPI gateway → order-servicehttp—/orders
Gcatalog-service → Redisdata—cache
Hcatalog-service → PostgreSQLdata——
Icart-service → Redisdata——
Jorder-service → PostgreSQLdata——
Korder-service → StripechannelAPI keypayment intent
Lorder-service → RabbitMQqueue—order.created
MRabbitMQ → notification-workerqueue——

How it works

Write the model. The picture, the docs and the replay follow.

One YAML file per diagram. Add a concept at a time and watch what it buys you. Each tab below is a real file, compiled and drawn by docspp as the page loaded.

Name the parts and say who talks to whom. Pick a kind and an icon for each node and docspp draws the cards. Edges become arrows, and the legend is generated. There are no coordinates in the file.

diagrams/photos/diagram.yaml
title: Photo uploads

nodes:
  browser: { kind: client, icon: react }
  api:     { kind: service, icon: nodejs, title: Upload API }
  store:   { kind: storage, icon: aws-s3, title: Storage }
  queue:   { kind: queue, icon: rabbitmq, title: Events }
  worker:  { kind: worker, icon: python, title: Thumbnailer }
  db:      { kind: database, icon: postgresql, title: Metadata }

edges:
  - browser -> api: POST /photos
  - api -> store: { kind: data, label: PUT }
  - api -> db: { kind: data, label: SQL }
  - api -> queue: { kind: queue, label: photo.uploaded }
  - queue -> worker: { kind: queue }
  - worker -> store: { kind: data, label: PUT }
  - worker -> db: { kind: data }

views:
  overview: { direction: DOWN }
HTTP request / responseData accessQueue / broker
Loading diagram…

Scenarios

One list of steps. Three ways to read it.

A scenario is a short list of steps: who sends what to whom. docspp turns it into packets over the architecture, a sequence diagram or a swimlane story, and keeps all three in step with the player.

paymentsPay with a card · 3 phases · 9 steps
Scenario

The shopper pays. We write the payment down first, charge the card second, and tell the rest of the system last, so a crash never loses money.

HTTP request / responseData accessPersistent channel (websocket, gRPC)Queue / brokerDashed: planned
Loading diagram…
IRecord itbefore any money moves
1
Web app→Payments APIPOST /payments

The request carries an idempotency key, so a retry cannot charge twice.

2
Payments API→Ledger databaseINSERT payment (pending)
IICharge the card
3
Payments API→Stripecreate payment intent
4
Stripeauthorise card

This is the only step we do not control, and the slowest one.

5
Stripe→Payments APIsucceeded
IIIFinish
6
Payments API→Ledger databasemark paid
7
Payments API→RabbitMQpayment.succeeded
8
Payments API→Web app201 Created
9
RabbitMQ→Receipt mailerpayment.succeededplanned

Receipts are planned. Today the shopper only sees the on-screen confirmation.

Make it yours

Restyle every diagram with a handful of CSS variables.

Every colour, font and shadow in a diagram is a --docspp-* token. Pick a palette and the diagram below changes. The snippet beside it is all the CSS that did it.

Scenario

The shopper pays. We write the payment down first, charge the card second, and tell the rest of the system last, so a crash never loses money.

HTTP request / responseData accessPersistent channel (websocket, gRPC)Queue / brokerDashed: planned
Loading diagram…
IRecord itbefore any money moves
1
Web app→Payments APIPOST /payments

The request carries an idempotency key, so a retry cannot charge twice.

2
Payments API→Ledger databaseINSERT payment (pending)
IICharge the card
3
Payments API→Stripecreate payment intent
4
Stripeauthorise card

This is the only step we do not control, and the slowest one.

5
Stripe→Payments APIsucceeded
IIIFinish
6
Payments API→Ledger databasemark paid
7
Payments API→RabbitMQpayment.succeeded
8
Payments API→Web app201 Created
9
RabbitMQ→Receipt mailerpayment.succeededplanned

Receipts are planned. Today the shopper only sees the on-screen confirmation.

src/styles/custom.css
/* Nothing to write: follows the site theme. */
.docspp {
  --docspp-accent: #0a6f8f;
}
src/styles/custom.css
.docspp {
  --docspp-bg: #0a2540;
  --docspp-surface: #0f3256;
  --docspp-zone: #0c2c4c;
  --docspp-ink: #e6f2ff;
  --docspp-muted: #9bbfe0;
  --docspp-line: #35689b;
  --docspp-accent: #7fd3ff;
}
src/styles/custom.css
.docspp {
  --docspp-bg: #050806;
  --docspp-surface: #0b110c;
  --docspp-zone: #08100a;
  --docspp-ink: #c9f7d3;
  --docspp-line: #1f4a2b;
  --docspp-accent: #4ade80;
  --docspp-sans: var(--docspp-mono);
}
src/styles/custom.css
.docspp {
  --docspp-bg: #fbfaf8;
  --docspp-surface: #ffffff;
  --docspp-zone: #f1f0ed;
  --docspp-ink: #121212;
  --docspp-line: #1f1f1f;
  --docspp-accent: #d4281c;
  --docspp-shadow: 3px 3px 0 #1f1f1f;
}

Dark mode takes its own set under :root[data-theme='dark'] .docspp. Every token is listed in the theming guide.

Icons

Your stack is already in the box.

icon: postgresql finds the logo. Brand logos, monochrome marks and generic UI icons are bundled at build time, so nothing is fetched in the browser. How icons are found.

  • postgresql
  • redis
  • kafka
  • rabbitmq
  • kubernetes
  • docker
  • nginx
  • terraform
  • grafana
  • prometheus
  • elasticsearch
  • mongodb
  • nodejs
  • go
  • python
  • rust
  • typescript
  • react
  • astro
  • graphql
  • cloudflare
  • stripe
  • keycloak
  • github-actions

For people and agents

Plain YAML that an agent can write and a machine can check.

The format is small, the schema is published and the validator is strict. Ask Claude Code, Cursor or Copilot to draw your architecture, and the loop below keeps the result honest.

  • A published JSON Schema

    docspp schema writes it next to your diagrams. Editors autocomplete every key, and agents stop guessing them.

  • Errors that say where

    File, line and column, with a hint that spells the right key. Add --json and a script can read them.

  • A broken diagram never ships

    The build fails on diagram errors, so a typo is caught on the pull request and not on the live site.

  • References that notice drift

    List the source files a box is based on. docspp check warns when one of them moves.

$npx skills add AhmeddBasemm/docspp --skill docspp
About the skill

Get started

One command to a running docs site.

The starter has a small shop diagram with three scenarios, a docs site around it and a GitHub Pages workflow. Edit the YAML, save, and the page reloads.

  • MITFree to use and change.
  • Node 22+And pnpm.
  • Astro + StarlightMarkdown pages, search, dark mode.
  • Static outputAny host works.
  1. Create the project
    $npm create docspp@latest my-docs
  2. Run it
    $cd my-docs && pnpm install && pnpm dev
  3. Draw your system

    Open diagrams/shop/diagram.yaml, rename a node, add an edge, press save. Or ask an agent to write the diagram from your code.

  4. Publish

    Enable GitHub Pages with the GitHub Actions source and push. The workflow is already there.