Skip to content

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.

Edit source — diagram updates live
Source
Loading diagram…

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.

order-context.kdiagram
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 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):

diagram.kdiagram
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 }
}
}

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.

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:

diagram.kdiagram
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.

Use the edge operator to encode the interaction shape:

diagram.kdiagram
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:

diagram.kdiagram
api -> orders "PlaceOrder" { priority: high }

Priority is a layout hint, not business severity.

Good group meanings include trust zones, ownership, deployment boundaries, and data planes:

diagram.kdiagram
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:

  1. a C4 context view for the system and its neighbors
  2. a C4 container view for applications and stores
  3. a C4 component view when the inside of one container is the question
  4. 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.