C4 Diagrams skill for Claude Code
Architecture diagrams as code that newcomers can read. Claude inventories the real system from compose files, infrastructure code and external API calls, then draws C4 context and container diagrams as code with one zoom level each. Every box names its technology and responsibility, every arrow states intent and protocol, and the sources live next to the code so they get updated in the same pull request.
- name
c4-diagrams - size193 lines · ≈2,100 tokens
- files1
- licenseMIT
- updated
What Claude sees before loading it
This description is the only part of the skill that sits in context all the time. Claude reads it to decide when to load the full playbook below.
description: Draws C4 model architecture diagrams (system context, container, component, plus deployment and dynamic views) as code in Mermaid or Structurizr DSL, with consistent notation, labeled relationships that state intent and protocol, legends, and one abstraction level per diagram. Covers deriving diagrams from a real codebase and infrastructure files, rendering with mermaid-cli or Structurizr, and keeping diagrams in sync with the code. Use when documenting a system's architecture, onboarding people to a codebase, preparing a design review diagram, or converting a whiteboard sketch into a maintainable diagram. Try asking
- Draw a C4 container diagram of this repo in Mermaid
- Turn this whiteboard photo of our system into a C4 context diagram
- Set up a Structurizr workspace with context, container and deployment views
Use it when
- Documenting a system's architecture for the team
- Onboarding people to an unfamiliar codebase
- Preparing a diagram for a design review
- Replacing stale wiki diagrams with diagrams as code
Skip it when
- You need flowcharts, ER or sequence diagrams generally: use mermaid-diagrams
- You want a written architecture overview of a new repo: use codebase-onboarding
How to check the result
Each diagram renders with a title, every element shows technology and responsibility, every arrow is labeled, and a check against compose and infra files finds nothing missing or stale.
The common mistake it prevents
Drawing unlabeled arrows and mixing zoom levels in one picture, which produces a diagram that looks informative but answers no question.
A good C4 diagram answers one question at one level of zoom, and a newcomer can read it without the author in the room: every box says what it is, what technology it uses, and what it does; every arrow says why and how. Diagrams as code, stored next to the code, are the only ones that stay current.
The levels
| Level | Shows | Audience | Typical count |
|---|---|---|---|
| 1. System context | Your system as one box, its users and external systems | Everyone, including non-technical | 1 per system |
| 2. Container | Deployable/runnable units: apps, services, databases, queues, SPAs | Engineers, ops, architects | 1 per system |
| 3. Component | Major components inside one container (modules, controllers, services) | Engineers working on that container | Only for complex containers |
| 4. Code | Classes/tables | Rarely worth drawing by hand; generate if needed | Almost never |
| Deployment | Containers mapped onto infrastructure (regions, clusters, nodes) | Ops, SRE | Per environment that differs |
| Dynamic | Numbered sequence of interactions for one use case | Engineers, reviewers | Per tricky flow |
“Container” in C4 means anything that runs or stores data separately (a web app, a Lambda, a Postgres database, an S3 bucket), not specifically a Docker container.
Notation rules
- Every element: name, type, technology (for containers/components), and a one-line responsibility. “API” alone is not a description.
- Every relationship: a verb phrase stating intent (“Places orders using”) and the protocol/technology (“JSON/HTTPS”, “SQL/TCP”, “AMQP”). Prefer one-directional arrows showing the dependency or data flow; be consistent.
- Title on every diagram stating type and scope: “Container diagram: Checkout”.
- A legend or key when colors/shapes carry meaning.
- One level per diagram. Do not mix containers and classes.
- 5–20 elements per diagram. More means split it or move detail down a level.
- Mark external systems distinctly (Mermaid
_Extelements, gray styling).
Workflow
- [ ] 1. Decide the question and audience; pick the levels needed
- [ ] 2. Inventory elements from code and infrastructure
- [ ] 3. Draft context diagram
- [ ] 4. Draft container diagram
- [ ] 5. Add component/dynamic/deployment views only where they answer a real question
- [ ] 6. Render, check readability, store as code next to the repo docs
2. Inventory from the real system
Do not draw from memory. Collect elements from:
ls apps/ services/ packages/ 2>/dev/null # deployable units in a monorepo
cat docker-compose.yml compose.yaml 2>/dev/null # services, DBs, queues
ls infra/ terraform/ k8s/ helm/ 2>/dev/null # deployed resources
grep -rhoE "https?://[a-z0-9.-]+\.(com|io|net)" src | sort | uniq -c | sort -rn | head # external APIs
grep -rlE "process\.env\.|os\.environ" src | head # config often names dependencies
Record each element with: name, kind (person/system/container/db/queue), technology, responsibility, and the relationships with protocol.
3–4. Mermaid C4
Mermaid’s C4 support is marked experimental; layout control is limited but it renders on GitHub and GitLab without extra tooling.
C4Context
title System context: Online Shop
Person(customer, "Customer", "Browses products and places orders")
Person(staff, "Support Staff", "Handles refunds and order issues")
System(shop, "Online Shop", "Storefront, checkout, and order management")
System_Ext(stripe, "Stripe", "Card payments")
System_Ext(postmark, "Postmark", "Transactional email")
Rel(customer, shop, "Browses and orders using", "HTTPS")
Rel(staff, shop, "Manages orders using", "HTTPS")
Rel(shop, stripe, "Charges cards via", "JSON/HTTPS")
Rel(shop, postmark, "Sends order emails via", "JSON/HTTPS")
C4Container
title Container diagram: Online Shop
Person(customer, "Customer")
System_Boundary(shop, "Online Shop") {
Container(web, "Storefront", "Next.js", "Server-renders catalog and checkout pages")
Container(api, "Orders API", "Node.js, Fastify", "Catalog, cart, checkout, orders")
Container(worker, "Worker", "Node.js, BullMQ", "Sends emails, processes webhooks")
ContainerDb(db, "Main DB", "PostgreSQL 16", "Products, orders, customers")
ContainerQueue(queue, "Job queue", "Redis", "Background jobs")
}
System_Ext(stripe, "Stripe", "Card payments")
Rel(customer, web, "Uses", "HTTPS")
Rel(web, api, "Calls", "JSON/HTTPS")
Rel(api, db, "Reads and writes", "SQL/TCP")
Rel(api, queue, "Enqueues jobs", "RESP")
Rel(worker, queue, "Consumes jobs", "RESP")
Rel(api, stripe, "Creates payment intents", "JSON/HTTPS")
Rel(stripe, api, "Sends webhooks", "HTTPS")
UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")
Directional variants (Rel_D, Rel_R, Rel_U, Rel_L) nudge layout. If Mermaid’s C4
layout becomes unreadable, fall back to a flowchart with C4-style labels (name,
[Container: tech], description) and subgraphs for boundaries; keep the same notation
rules.
Render locally:
npx -p @mermaid-js/mermaid-cli mmdc -i docs/architecture/containers.mmd -o docs/architecture/containers.svg
Structurizr DSL (model once, many views)
Prefer it when there are several systems or many views that must stay consistent: you define the model once and each view is a projection.
workspace "Online Shop" {
!identifiers hierarchical
model {
customer = person "Customer" "Browses products and places orders"
stripe = softwareSystem "Stripe" "Card payments" { tags "External" }
shop = softwareSystem "Online Shop" {
web = container "Storefront" "Server-renders catalog and checkout" "Next.js"
api = container "Orders API" "Catalog, cart, checkout, orders" "Node.js, Fastify"
db = container "Main DB" "Products, orders, customers" "PostgreSQL 16" { tags "Database" }
}
customer -> shop.web "Uses" "HTTPS"
shop.web -> shop.api "Calls" "JSON/HTTPS"
shop.api -> shop.db "Reads and writes" "SQL/TCP"
shop.api -> stripe "Creates payment intents" "JSON/HTTPS"
}
views {
systemContext shop "Context" { include * autolayout lr }
container shop "Containers" { include * autolayout lr }
styles {
element "Database" { shape cylinder }
element "External" { background #999999 color #ffffff }
}
}
}
Render with Structurizr’s own tooling (Lite/on-premises UI) or export views to other formats with the Structurizr CLI (for example to Mermaid or PlantUML). Check the current Structurizr documentation for the exact distribution and commands the team uses.
5. Supplementary views
- Dynamic: number the steps for one use case (checkout with 3-D Secure, webhook
retry). Often clearer as a Mermaid
sequenceDiagram(see mermaid-diagrams). - Deployment: map containers to regions, clusters, managed services, and replicas per environment. Include what is redundant and what is a single instance.
- Component: only for containers with non-obvious internal structure; derive from module folders and their imports.
6. Store and maintain
- Keep sources in
docs/architecture/(.mmd,.mdwith fenced mermaid, orworkspace.dsl); commit rendered SVGs only if the docs site cannot render them. - Link diagrams from the README and relevant ADRs.
- Update diagrams in the same PR that adds or removes a container or external dependency; add it to the PR template checklist.
Gotchas
- Unlabeled arrows are the most common defect; they make the diagram decorative.
- Showing every microservice-to-microservice call creates a hairball. Group or split by domain.
- Mixing runtime and deployment concerns (pods, load balancers) into the container view confuses readers; that belongs in the deployment view.
- Message brokers drawn as a hub with every arrow through them hide who actually depends on whom; label arrows with topic/queue names.
- Colors with no legend carry no meaning for the reader.
Verification
- Every element has name, technology (where applicable), and a responsibility; every arrow has intent and protocol.
- Each diagram renders without errors and has a title.
- Cross-check against the inventory: no deployed service, database, or external API is missing; nothing in the diagram no longer exists.
- Ask: can someone new answer “where does an order get stored and who calls Stripe?” from the diagrams alone.
About this skill
Written and maintained by the Claude Skills editors to the same editorial standard as every skill in the directory: a selective trigger, a real workflow, known pitfalls and a verification step. First published , last updated . MIT licensed.