Architecture diagrams
An architecture diagram should help a reader reason about responsibilities and interactions. It should not attempt to prove that every service, queue, and database exists.
Begin with a boundary and a path
Section titled “Begin with a boundary and a path”Choose one scope:
- Context: people and software systems around one system of interest.
- Container: separately running applications and data stores inside that system.
- Component: collaborators inside one container.
- Interaction: one request, command, or event path — a different question than C4 structure.
Mixing those levels usually produces a picture where a person, a browser app, and a class look like peers.
diagram "Order context" { direction TD presentation { showKindSubtitles: true }
buyer: person "Buyer" { description: "Places orders with the commerce platform." }
boundary company "Commerce Co." { shop: system "Commerce platform" { description: "The software system of interest." } }
payments: external "Payment provider" { description: "Authorizes card charges." }
buyer -> shop "Places orders [HTTPS]" shop -> payments "Authorizes payments [HTTPS]"}C4 views
Section titled “C4 views”C4 is a set of zoom levels, not a second Kekonic dialect. Prefer one
kdiagram 2 model with embedded views when context, containers, and components share
topology — then switch lenses with --view or the live host picker instead of copying files:
| View | Show | Kinds |
|---|---|---|
| System Context | People and software systems around the system of interest | person, system, external |
| Container | Applications and data stores inside that system | container (use shape: cylinder for databases), plus people and external systems they still talk to |
| Component | Important parts inside one container | component, with neighboring containers left closed |
boundary draws the enterprise on a context diagram and the software system (or opened container)
on the next zoom. Kind subtitles name the C4 type (Person, Software System, External System,
Container, Component). description is the body text; technology is the tech tag. Relationship
labels should say how or why, with optional [technology] — not calls. C4 is a set of views, not
a color scheme: Kekonic Diagrams uses the product theme. Kinds are distinguished by type line, shape
(person silhouette, cylinder stores), size, and border (externals are dashed)—not Structurizr’s
default palette.
Worked example — one model, multiple lenses. Minimal shape (full syntax in the language reference):
kdiagram 2
model "Storefront" { customer: person "Customer" platform: system "Commerce platform" boundary commerce "Commerce platform" { web: container "Web application" api: container "API application" } stripe: external "Stripe"
view context { include customer, platform, stripe customer -> platform platform -> stripe layout { direction: TD } }
view containers { include customer, commerce.*, stripe customer -> web web -> api api -> stripe layout { direction: LR; groupLayout: compound } }}- Storefront — shared model with views (context, containers, and components from one source)
Kekonic Diagrams does not currently provide a C4 code view (UML classes). Skip that level, or use a dedicated UML tool. The language also does not enforce C4 rules: you can mix levels, and the compiler will not stop you. Keep one C4 abstraction per view on purpose.
A container is a separately running application or data store, not a Docker image. For
event-driven topology (topics, outbox, DLQ) use a focused path diagram such as
order fulfillment rather than stuffing the broker into a context
view.
Show the right level of detail
Section titled “Show the right level of detail”Kinds such as person, system, container, service, gateway, database, broker, and
external give readers semantic cues. They are not a substitute for consistent abstraction.
If the diagram is a system context, prefer person, system, and external. If it is a C4
container view, use container (not a mix of gateway and system as peers). service and
gateway belong in non-C4 architecture maps. Introduce technology names as secondary details, not
as the primary label:
orders: container "API application" { technology: "Node.js" description: "Accepts orders and records the outbox."}The label explains the responsibility. The technology and note support it.
Make connections mean something
Section titled “Make connections mean something”Use the edge operator to encode the interaction shape:
api -> orders "PlaceOrder"orders -> database "insert"orders => bus "OrderPlaced"reporting ..> database "read replica"orders -x deadLetter "after 5 attempts"Labels should answer one of four questions: what, how, when, or under what condition.
Do not label an edge calls when the arrow already says that.
For a visually important path, priority: high asks layout to favor it:
api -> orders "PlaceOrder" { priority: high }Priority is a layout hint, not business severity.
Use groups for facts
Section titled “Use groups for facts”Good group meanings include trust zones, ownership, deployment boundaries, and data planes:
group application "Application" { api: gateway "API" orders: service "Orders"}
group data "Data plane" { database: database "Postgres" events: broker "Kafka"}Avoid boxes titled “Backend” or “Misc” unless that distinction genuinely helps the reader.
Split before the diagram becomes a map of everything
Section titled “Split before the diagram becomes a map of everything”A strong architecture set often contains several diagrams of the same system:
- a C4 context view for the system and its neighbors
- a C4 container view for applications and stores
- a C4 component view when the inside of one container is the question
- a path view for a critical interaction or failure mode
Reuse names across views. Do not force them onto one canvas. Domain-driven design has its own zooms — event storm, context map, aggregate — see DDD views. Continue with Control layout when the model is right but the visual hierarchy needs help, or browse the architecture gallery.