by Guillermo Quiros
A practical guide to C4 Code diagrams — Level 4 of the C4 model and the one level most teams should use sparingly or skip entirely.
Need the broader model first? Visit the C4 model hub and return here for the Code diagram deep dive.
What Is a C4 Code Diagram?
A **C4 code diagram** is Level 4 of the C4 model. It zooms into a single component from a Component diagram (Level 3) and shows how that component is implemented — typically using a UML class diagram, an entity-relationship diagram, or another implementation-level notation.
Where Level 3 shows which components exist inside a container, Level 4 shows how a specific component is built. It is the closest zoom the C4 model goes to actual source code.
The defining characteristic of Level 4 is that it is generated, not hand-drawn. The C4 model guidance is explicit on this point: code diagrams that are drawn and maintained by hand go stale almost immediately. The only sustainable Level 4 diagrams are ones your tooling produces automatically from the codebase — an IDE plugin, a reflection-based diagram generator, or a schema export tool.
When Is Level 4 Worth Drawing?
Most teams should not draw Level 4 diagrams. That is not a criticism — it is the model's own recommendation. The code level only earns its keep in a narrow set of circumstances.
The component is complex enough to benefit from a structural view. A domain aggregate with fifteen entities, a rules engine with a deep inheritance hierarchy, or a data pipeline with a branching transformation graph are candidates. A CRUD service with four methods is not.
The audience needs implementation detail, not just structural context. Code reviewers, new engineers onboarding onto a specific component, and architects evaluating refactoring options sometimes need the Level 4 view. If the audience only needs to understand what the system does and how its parts fit together, Levels 1–3 are sufficient.
Tooling can keep it current. If you cannot generate the diagram automatically, do not draw it. A hand-maintained class diagram that is three months out of date actively misleads readers.
What a Code Diagram Shows
Level 4 uses notation from existing standards rather than inventing new C4-specific shapes. The most common choices are:
UML Class Diagrams
Class diagrams are the most widely used Level 4 notation. They show classes, interfaces, their attributes and methods, and the relationships between them (inheritance, composition, aggregation, dependency). Use them when the component is implemented in an object-oriented language and the class structure is the primary thing worth documenting.
Keep class diagrams scoped tightly. Show the classes that make up the component being documented, not the entire package tree. Omit getter and setter boilerplate — include only the methods and properties that are architecturally significant.
Entity-Relationship Diagrams
ER diagrams are the right choice when the component is primarily a data model — a persistence layer, a schema, a reporting aggregate. They show entities (tables or document types), their attributes, and the relationships between them with cardinality.
ERDs generated directly from a migration tool or an ORM schema are the most reliable because they cannot drift from the actual data structure.
Other Notation
The C4 model does not mandate a specific Level 4 notation. If your domain is better represented by a state machine diagram, a data flow diagram, or a custom schema representation, use that. The goal is clarity for the intended audience, not conformance to a specific diagram format.
Scope: What Belongs on a Code Diagram
A code diagram documents one component from the Level 3 Component diagram. It should not span multiple components, attempt to show the entire container's implementation, or reproduce the Component diagram at a lower zoom.
If you find yourself drawing lines that cross component boundaries on a Level 4 diagram, you are likely documenting an interaction that belongs on a dynamic diagram rather than a structural code view.
Practical scope guidance:
- Include every class or entity that is part of the component's public surface and core logic
- Exclude third-party library internals unless they are extended or decorated in a way that changes their contract
- Exclude generated code (proto files, ORM-generated models) unless the generation configuration itself is the thing being documented
- Exclude test classes
How to Build a Code Diagram
Step 1: Confirm the component exists in Level 3
A Code diagram must extend a specific component from your Component diagram. If the component is not drawn at Level 3, draw it there first. Level 4 without a Level 3 parent is an orphan diagram — readers have no context for what they are looking at.
Step 2: Choose the notation that fits the implementation
Pick UML class diagrams for object-oriented code, ER diagrams for data models, and state machine diagrams for components driven by explicit state transitions. Mixing notations on a single diagram creates confusion.
Step 3: Prefer generation over hand-drawing
Set up your tooling to generate the diagram from source. Options include:
- IDE plugins that export class diagrams from selected packages
- ORM tools that generate ER diagrams from schema migrations
- Reflection-based tools that produce diagrams from runtime or static analysis
- Documentation pipelines that embed generated diagrams in your docs system
If generation is not possible, schedule a short review cadence (monthly or at each significant release) to verify the diagram still matches the code.
Step 4: Scope ruthlessly
Export or draw only the classes, entities, or nodes that belong to the component. Remove noise. A diagram that shows one hundred classes for a component with twenty significant ones makes the twenty harder to find, not easier.
Step 5: Add context
Label the diagram with the component name, its parent container, and the date it was generated. Readers who arrive at a code diagram from a search result or a documentation link need to know where they are in the C4 hierarchy.
Common Mistakes
Maintaining it by hand. Code changes every day. A hand-drawn Level 4 diagram is almost always out of date. If you cannot generate it, reconsider whether it is worth having.
Drawing Level 4 before Level 3. Teams sometimes jump straight to code-level detail without an intermediate Component diagram. This produces a diagram that has no anchor in the broader architecture story. Draw Level 3 first.
Scoping too broadly. A Level 4 diagram that attempts to show the entire container's implementation is a redrawn Component diagram drawn badly. Keep each Level 4 diagram to one component.
Using it as a substitute for tests or contracts. A class diagram does not tell you what the code guarantees, only what it contains. Code diagrams complement tests and interface documentation — they do not replace them.
Distributing read-only images. Code diagrams embedded as static images in wikis or slide decks become stale and cannot be clicked into. Store them as living diagrams linked to generation tooling wherever possible.
Level 4 and the Rest of the C4 Hierarchy
The C4 model is designed to be used selectively. Most software systems only need Levels 1 and 2 for the majority of their architecture documentation. Level 3 is valuable for components with significant internal complexity. Level 4 is the exception, not the rule.
A useful framing: draw the lowest level that answers the audience's question. If a new engineer asks "how does the payment processing component work internally?", Level 4 might be the right answer. If they ask "what services does the payment system depend on?", Level 2 is the right answer. Using a higher-zoom diagram for a lower-zoom question wastes the reader's attention.
When Level 4 is appropriate, it pairs best with dynamic diagrams that show the same component's runtime behaviour. The Code diagram shows the static structure; the dynamic diagram shows how that structure comes to life during a specific flow.
Frequently Asked Questions
Do I have to use UML for Level 4?
No. The C4 model does not mandate UML. It recommends UML class diagrams and ER diagrams as common choices because most engineers recognise them, but any notation that communicates the implementation structure clearly to the intended audience is acceptable.
Can a code diagram span multiple components?
No. Each Level 4 diagram documents one component from the Level 3 diagram. If you need to show how two components interact, use a dynamic diagram, not a Level 4 code diagram.
What if my component has hundreds of classes?
Either the component is too large (and should be split into multiple components at Level 3), or the diagram is scoped too broadly. A useful Level 4 diagram shows the architecturally significant classes — typically no more than ten to twenty — not every class in a package.
Is it acceptable to skip Level 4 entirely?
Yes. For most systems and most components, Levels 1–3 provide sufficient documentation. Level 4 is optional and should only be drawn when there is a specific audience that needs implementation-level detail and a way to keep the diagram current.
How does Level 4 relate to code generation tools like Swagger or Javadoc?
They serve different purposes. Swagger and Javadoc document API contracts and method signatures — the public interface. A C4 Code diagram documents the internal structure of a component — the classes, entities, and relationships that implement the behaviour behind that interface. Both are useful; neither replaces the other.