Diagram DSL: Draw Architecture from Text

The ArchBoard diagram DSL: nodes, edges, labels, replicas, layouts and a dozen copy-paste examples. Type text and get an editable, auto-laid-out diagram.

Why text

Dragging boxes is good for exploring, but a text description is faster to write, easy to review in a pull request and trivial to change. The ArchBoard DSL turns a few readable lines into real Excalidraw shapes, with icons, bound arrows and an automatic layout, so you can then tweak the result by hand like any other drawing.

Grammar

One statement per line. A node is kind [tech] ["label"]. Give it an id with kind id "label" to refer to it later; a node without an id is referred to by its label in lower case with dashes. Edges join nodes: a -> b (solid), a --> b (dashed), a <-> b (two-way) and a -[label]-> b (labelled). Chain edges on one line, and write [api x3] to draw three replicas. Directives: direction LR or TB, layout tree, radial or layered, and title "…".

Limits: 150 nodes and 12 replicas per diagram. Errors appear as wavy underlines in the editor (Tools, then Diagram from text) and nothing is inserted until the text is valid.

Node kinds

actor, api, apigateway, app, auth, browser, bucket, bus, cache, cdn, ci, cicd, client, container, container_, cron, database, db, dns, eventbus, ext, external, firewall, flags, fn, function, gateway, idp, job, kafka, lambda, lb, loadbalancer, microservice, microsvc, mobile, monitor, mq, node, nosql, observability, people, pipeline, pod, proxy, pubsub, queue, ratelimiter, redis, reverseproxy, s3, scheduler, search, service, sql, storage, stream, svc, thirdparty, timer, topic, user, vault, waf, warehouse, web, worker.

Examples

Service and database

The smallest useful diagram: a service reading from a PostgreSQL database.

service api "Orders API" -> db postgres "Orders DB"

Load-balanced replicas

A load balancer fanning out to three replicas, with an event queue behind them.

service api "Orders API" -> db postgres "Orders DB"
lb "Edge LB" -> [api x3]
api -> queue kafka "order-events" -> worker "Fulfilment"

URL shortener

Read-heavy write path with a cache in front of the database and a CDN for redirects.

title "URL shortener"
client "Browser" -> cdn "CDN" -> lb "LB" -> service app "Shortener"
[app x3]
app -> cache redis "Hot links"
app -> db postgres "Links DB"
app -[async]-> queue kafka "click-events" -> worker "Analytics" -> warehouse snowflake "Clicks"

Event-driven checkout

Checkout publishes an order event; payments, inventory and email react independently.

direction LR
client "Web app" -> gateway "API gateway" -> service checkout "Checkout"
checkout -> topic kafka "orders"
orders -> service payments "Payments"
orders -> service inventory "Inventory"
orders -> function lambda "Send email"
payments -> external stripe "Stripe"

Cache-aside

The application checks Redis first and falls back to PostgreSQL on a miss.

service app "Application"
app -[1. get]-> cache redis "Redis"
app --[2. on miss]--> db postgres "Postgres"

API gateway and microservices

A gateway with authentication routing to independent services that own their data.

browser "Web" -> gateway "API gateway" -> auth auth0 "Auth0"
gateway -> microservice users "Users"
gateway -> microservice orders "Orders"
gateway -> microservice catalog "Catalog"
users -> db postgres "Users DB"
orders -> db mysql "Orders DB"
catalog -> search elasticsearch "Catalog index"

CQRS

Commands go through a write model; events keep a read model up to date for queries.

layout right
client "Client" -> service cmd "Command API" -> db postgres "Write model"
cmd -> topic kafka "events"
events -> worker proj "Projector" -> search elasticsearch "Read model"
client --[query]--> service qry "Query API" -> search elasticsearch "Read model"

Pub/sub fan-out

One publisher, one topic, many subscribers.

service pub "Publisher" -> topic sns "orders.created"
orders-created -> worker billing "Billing"
orders-created -> worker shipping "Shipping"
orders-created -> worker notify "Notifications"

Batch ETL

Sources land in object storage, a scheduled job transforms them and loads the warehouse.

direction LR
db mysql "Orders DB" -> storage s3 "Raw zone" -> worker spark "Transform" -> warehouse snowflake "Warehouse"
external "Partner API" -> raw-zone
cron "Nightly job" -> spark

CDN with origin

Users hit the CDN, which only reaches the origin on a cache miss.

user "Visitors" -> cdn cloudfront "CDN"
cdn --[miss]--> lb "Origin LB" -> service origin "Origin"
[origin x2]
origin -> storage s3 "Assets"

Observability

Services emit metrics and logs to a collector feeding Prometheus and Grafana.

service a "Service A" -> monitor prometheus "Prometheus" -> monitor grafana "Grafana"
service b "Service B" -> prometheus
service c "Service C" -> prometheus

CI/CD pipeline

A push triggers CI, which builds a container, stores it in a registry and deploys to Kubernetes.

direction LR
client "Developer" -> ci github "GitHub Actions" -> container docker "Image build" -> storage s3 "Registry" -> pod k8s "Kubernetes"
vault "Secrets" -> github-actions

Try it with a template

Last updated 2026-10-07.