Practice
C4 with PlantUML: diagrams as text
Text-based diagrams review like code, diff like code and survive like code. Here is how PlantUML fits a C4 model — and where writing everything by hand stops paying.
Why text
A diagram stored as an image is a binary blob: it cannot be diffed, reviewed, or merged, and the source file that produced it is usually on someone's laptop. A diagram stored as text goes through code review with the change that caused it.
PlantUML is the most common way to do that, and the C4-PlantUML library adds the C4 vocabulary directly — `Person`, `System`, `Container`, `Component`, and relationship macros that force you to label the arrow.
A Container diagram in C4-PlantUML
Note that every `Rel` takes a label and a protocol. The library makes the useful thing the easy thing.
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
Person(customer, "Customer", "Holds an account")
System_Boundary(banking, "Internet Banking System") {
Container(spa, "Single-Page Application", "React", "Account and payment UI")
Container(api, "API Application", "Java, Spring Boot", "Business logic and endpoints")
ContainerDb(db, "Database", "PostgreSQL", "Accounts, payments, audit log")
}
System_Ext(mainframe, "Mainframe Banking System", "System of record")
Rel(customer, spa, "Uses", "HTTPS")
Rel(spa, api, "Calls", "JSON/HTTPS")
Rel(api, db, "Reads from and writes to", "JDBC")
Rel(api, mainframe, "Fetches balances from", "XML/HTTPS")
@endumlSequence diagrams that stay honest
Sequence diagrams are where abstraction levels quietly collapse. A single diagram ends up with a user, a container, a class and a vendor, and the reader silently learns a wrong model of the system.
The discipline that fixes it is simple: pick the level first, then only allow participants from that level. A container-level sequence has containers as participants. A component-level sequence has components from one container. Anything else is a different diagram.
@startuml
participant "Single-Page Application" as SPA
participant "API Application" as API
participant "Database" as DB
participant "Mainframe Banking System" as MF
SPA -> API : POST /payments (JSON/HTTPS)
API -> DB : INSERT payment (pending)
API -> MF : authorise funds (XML/HTTPS)
MF --> API : authorisation code
API -> DB : UPDATE payment (settled)
API --> SPA: 201 Created
@endumlWhere diagrams-as-code stops paying
Text is excellent for a diagram. It is poor for a model. Once you have thirty `.puml` files, nothing connects them: renaming a container means grepping, there is no way to ask "what depends on this database", and drilling from a container into its components is a matter of guessing filenames.
That is the point at which teams move from drawing diagrams to holding a model — one set of elements, many views generated from it — while keeping text export for the parts that genuinely belong in the repository.
A reasonable middle
Model the structure in a tool, keep sequences as text next to the code, and make sure the two share the same element names.
Frequently asked
What is C4-PlantUML?
An open-source PlantUML standard library that adds C4 elements and relationship macros, so C4 diagrams can be written as text and rendered in CI, in a wiki, or in an IDE preview.
Should sequence diagrams mix containers and classes?
No. Pick one abstraction level per diagram. Mixing levels is the fastest way to make a sequence diagram misleading rather than merely incomplete.
Is Mermaid a good alternative to PlantUML for C4?
Mermaid renders natively in GitHub and many wikis, which is a real advantage, and it has an experimental C4 syntax. PlantUML has the more mature C4 library. Either is better than a PNG with no source.
The guide
The rest of the guide
Eight short pages covering the four levels, the notation, the comparisons people ask about, and the tooling decisions that only hurt six months in.
Level 1
The System Context diagram
One box for your system, the people who use it, and the systems it depends on. It is the only architecture diagram that a product manager, a security reviewer and a new engineer can all read on their first day.
Level 2
The Container diagram
The separately deployable pieces inside your system and the technology each one is built with. If a team draws only one architecture diagram, this is the one that earns its keep.
Level 3
The Component diagram
The major building blocks inside one container, what each is responsible for, and how they collaborate. Drawn per container, and only for the containers that are genuinely hard.
Level 4
The Code diagram
Classes, interfaces and their relationships inside a single component. The level almost everybody draws first and almost nobody should maintain by hand.
Comparison
C4 vs UML, ArchiMate and "boxes and lines"
C4 is not competing with UML — it is solving a different problem. Knowing which problem each one solves is what stops an architecture review turning into a notation argument.
Comparison
C4 and arc42
These two get compared as if you had to pick one. You do not: arc42 is the shape of the document, C4 is what goes in the picture. Teams that understand that use both and stop arguing.
Comparison
Structurizr, and when to use something else
Structurizr is the reference implementation of C4, written by the person who invented C4. That is a real argument in its favour and worth saying before any comparison starts.
Practice
C4 with PlantUML: diagrams as text
Text-based diagrams review like code, diff like code and survive like code. Here is how PlantUML fits a C4 model — and where writing everything by hand stops paying.
Comparison
C4 tools compared
Drawing tools, diagrams-as-code and modelling tools solve different halves of the problem. The right choice depends on whether you are producing pictures or maintaining a model — and on whether the model has to stay on your own machine.
See it as a model rather than a picture
Viaduct puts all four levels in one navigable model with the documentation attached. It runs locally in the browser — no account needed.
