Open standard · v0.2 preview · Apache-2.0 + CC BY 4.0

Architecture you can read, check and diff.

ArchCode is a text notation for software architecture — C4 with types. Three lines make a diagram, a linter can reason about it, and when you drag a card the text changes by one line.

npm i -g archcode@preview
archcode.io/play — live, this is the real editor
ArchCode diagram — 4 objects, 3 relations HTTPS SQL order.placed Customer · [actor]Customer[actor] Checkout · [service] · GoCheckout[service]Go Orders DB · [datastore] · PostgreSQL 16Orders DB[datastore]PostgreSQL 16 Billing · [service] · KotlinBilling[service]Kotlin ArchCode diagram — 4 objects, 3 relations HTTPS SQL order.placed Customer · [actor]Customer[actor] Checkout · [service] · GoCheckout[service]Go Orders DB · [datastore] · PostgreSQL 16Orders DB[datastore]PostgreSQL 16 Billing · [service] · KotlinBilling[service]Kotlin
The notation

Three lines, a real diagram.

No shapes, no coordinates. service and datastore are kinds, so the renderer knows a store is a cylinder that sits under the service owning it. writes is a verb, so a rule can say "a service writes a store it does not own".

service   checkout  "Checkout"   tech Go
datastore orders_db "Orders DB"  tech "PostgreSQL 16"  owned_by checkout

checkout writes orders_db over SQL
ArchCode diagram — 2 objects, 1 relations SQL Checkout · [service] · GoCheckout[service]Go Orders DB · [datastore] · PostgreSQL 16Orders DB[datastore]PostgreSQL 16 ArchCode diagram — 2 objects, 1 relations SQL Checkout · [service] · GoCheckout[service]Go Orders DB · [datastore] · PostgreSQL 16Orders DB[datastore]PostgreSQL 16
Everything an architecture has to say

Nothing a drawing tool would let you say wrong.

C4 with types

The levels of C4 — context, container, component — with level 2 typed: a kind, not a tag.

systemservicewebappgatewaybrokerdatastorecachefunctionjobcomponentactorexternal

Verbs, not arrows

Eight verbs a linter understands. The protocol goes to over, the path through gateways and brokers to via.

api   calls     billing over gRPC via gw
api   writes    orders  over SQL
api   publishes order.placed via kafka

Contracts by pointer

The fact, the address and the revision — never a copy of the schema. Depth stays with OpenAPI, AsyncAPI, proto and SQL.

checkout exposes http   openapi://checkout.yaml @9f3c
orders_db stores  schema sql://orders.sql

Layout is computed — and yours when you want it

Cards are placed by the engine. Drag one and the arrows stretch instead of being redrawn, draw.io-style; pin the view and the positions become a few lines in the file, so a diff still reads.

view main {
  at checkout 240 120
  route checkout writes orders_db from right to left label 0.4 below
}

Where it runs

env, cluster, node, run … cpu 0.5 mem 512Mi — the deployment picture and a resources table fall out of the same file.

ArchCode diagram — 6 objects, 1 relations Production · [env]Production[env] Kubernetes · [cluster] · ×3 · 8 cpu · 32GiKubernetes[cluster]×3 · 8 cpu · 32Gicpu 2.5/24 · mem 2.5/96Gi Managed Postgres · [managed]Managed Postgres[managed] SQL Checkout · [service] · Go · ×3 · 0.5 cpu · 512MiCheckout[service]Go×3 · 0.5 cpu · 512Mi Billing · [service] · Kotlin · ×2 · 0.5 cpu · 512MiBilling[service]Kotlin×2 · 0.5 cpu · 512Mi Orders DB · [datastore] · PostgreSQL 16Orders DB[datastore]PostgreSQL 16 ArchCode diagram — 6 objects, 1 relations Production · [env]Production[env] Kubernetes · [cluster] · ×3 · 8 cpu · 32GiKubernetes[cluster]×3 · 8 cpu · 32Gicpu 2.5/24 · mem 2.5/96Gi Managed Postgres · [managed]Managed Postgres[managed] SQL Checkout · [service] · Go · ×3 · 0.5 cpu · 512MiCheckout[service]Go×3 · 0.5 cpu · 512Mi Billing · [service] · Kotlin · ×2 · 0.5 cpu · 512MiBilling[service]Kotlin×2 · 0.5 cpu · 512Mi Orders DB · [datastore] · PostgreSQL 16Orders DB[datastore]PostgreSQL 16

Checked, with a line and a column

An unresolved reference, an ambiguous id, a run outside a host, a store written by a service that does not own it — reported as you type, in the CLI, in VS Code. A broken file still yields a model; nothing ever throws.

archcode.arch:14:3  warning  AC101  calls target `nobody` is not declared anywhere
archcode.arch:22:5  error    AC108  `run` only makes sense inside an env, cluster or node

Goes everywhere

SVG with fonts embedded, PNG, a compiled JSON/YAML form for tools, a CLI for CI, a VS Code preview, a share link that is the document.

SVGPNGJSONYAMLCLIVS Codelink
One model, every picture

You write the system once.
The lens decides what you see.

The real C4 experience

Add a component inside a service — that is C3. Select three cards and group them into a system — that is C1 around C2. Fold the system to one box, press balance. Three levels, one file, nothing redrawn by hand.

Logical

What talks to what. Type a card — service profile "Profile" — and a line — profile_ui calls profile — and they are on the canvas; drag a card and its arrows stretch instead of being redrawn. The kinds decide the shapes; you never draw a box.

Infrastructure

Flip the switch and the plumbing steps out of the arrows: every gateway and broker becomes a card, every hop an arrow. Same file — nothing was redeclared.

Deployment

Where things run — environments, clusters, managed services, nodes — with agents on the hosts and the load each host carries. Drag a card: the frame hugs it and the arrows follow.

Resources

What it all needs, summed per environment — and per moment, when the file says at 2027-01 count 6. Ask for more than the cluster has and the row says so; give the managed store a size and the total grows.

See it in action

The Playground is an editor, not a viewer.

Arrows you can grab
Arrows you can grabSlide a segment, move a bend, drop an end on another card — the relation line in the text follows.
Deployment from the same file
Deployment from the same fileEnvironments, clusters, managed services, nodes; agents on the hosts; load per host.
Resources, summed
Resources, summedcpu · mem · disk per environment and per moment, straight from run … cpu 0.5 mem 512Mi.
Dark or light
Dark or lightOne switch for the chrome, the picture and the export.
SVG with fonts, or PNG
SVG with fonts, or PNGA file that looks the same in Keynote, Confluence and a chat.
Keys & gestures
Keys & gesturesSpace to pan, F to fit, ⌘S to pin the view into the file, ⌘Z for everything.
ArchCode vs. the rest

Drawing tools draw. Modelling tools model. This one does both, in text.

ArchCodeStructurizr DSLMermaid / C4-PlantUMLdraw.io / Excalidraw
Semantic kinds (a store is a store)●◐ tags◐ C4 macros○
Verbs a rule can read●○○○
Validation with line and column●◐○○
Layout computed, not stored●●●○
Drag on the canvas → the text changes●○○—
Deployment with sizes and a resources table●◐ no sizes○○
Contracts by pointer (OpenAPI, proto, SQL)●◐ url○○
Runs without a server●◐●●
Open specification, permissive license● CC BY · Apache◐ Apache tooling●●

● yes · ◐ partly · ○ no. Coming from Structurizr? Most of a workspace carries over.

Quick start

Three ways in. Five minutes each.

1

In the browser

Nothing to install. Write, drag, share a link — the document travels inside the URL.

Open the Playground
2

In a repository

One archcode.arch beside the README; render it in CI, check it in a pre-commit hook.

npm i -g archcode@preview
archcode render archcode.arch -o architecture.svg
archcode check archcode.arch
3

On your machine

The VS Code extension previews .arch beside the file — Cursor, Windsurf and VSCodium take it too. The Playground alone ships as a container for your own network — no site, no server, nothing leaves it.

Download the extension · archcode-0.2.2.vsix
code --install-extension archcode-0.2.2.vsix
docker run -p 8080:80 ghcr.io/archcode-io/playground

Open VSX and the Marketplace follow the public preview; until then the file above is the extension.

Questions

Short answers.

The long ones are in the why page and the specification, which says for every section what is implemented, partial or planned.

Yes — the same levels: context, container, component. What ArchCode adds is a type for every container (service, datastore, broker…) instead of a tag, because rules and renderers can reason about a type and not about a tag. container is there for when you do not know yet.

The language is CC BY 4.0, the engine, CLI, site and Playground are Apache-2.0, and that was decided before the first commit precisely so it cannot change later. Self-host the Playground; nothing calls home.

Nowhere. The link is the document — compressed into the URL, the part after the #, which a browser never sends to any server. There is no account. The site's pages count visits (Yandex Metrica); the Playground has no counter at all, so nothing you draw can reach one.

Structurizr is the closest relative: a DSL for a C4 model with views. ArchCode types the containers, gives relations verbs a linter can read, computes layout, and lets the canvas edit the text. Styles and per-view layout are left out on purpose. The full map.

Not yet — that is the extractor, later on the roadmap. Today the file is written by hand and checked by the engine; the CLI renders it in CI so the picture in the wiki is never older than the file.

The words the parser already keeps but does not read: decision (ADRs in the model), rule (a three-form mini-language: forbid, require, warn), profile. Every section of the spec says what is implemented, partial, reserved or planned.

Write the system down once.

Then let the pictures, the checks and the answers come from the file.