We are considering using C4 for our architecture diagrams. Many diagramming tools (including Structurizr which was developed specifically for it) support C4. I wonder if there are others that use it and I would like to hear your experiences.
My initial assessment is as follows:
Pros
- Diagram as code is a great way to keep things open to change.
- It allows for better versioning
- It enforces semantics into the diagrams. Instead of just thinking in terms of boxes and arrows, one need to dig deeper
Cons
- It has a relative steep learning curve (one needs to study the DSL even though the end result is just boxes and arrows)
- The tooling is not perfect. One needs to run a docker container to be able to navigate within the diagram (solution: there is also a SaaS offering)
- Its view of architecture is somewhat limiting. It doesn’t seem to be catered for augmenting the diagrams with other forms of diagrams (flowcharts, etc.) or text.
I’ve used it with a lot of success at my current and previous companies. To address a few of your cons:
-
Engineers are quickly comfortable with the tooling and VS Code plugins give you quick feedback. You can also point the plug in at a hosted instance to avoid running a local instance in Docker
-
Separation of different types of diagram is often a bonus—too often have I seen architects try to cover too many concepts in a single diagram—instead a Context diagram should define your system and its neighbours, a Container diagram the major pieces of your system, a Component diagram verges on design and is a good place for engineers and architects to converse. If a container or component has a particularly complex workflow, then a supplementary flow diagram helps. If it uses an extraordinary pattern, then a class diagram might help, and so on.
My main concern is this: We have a wiki, each component has some sort of a README. If we add C4 to the mix, then we will have technical documentation in 3 different places. I would love it if C4 would eliminate the need for a wiki. Then in a CI pipeline, we would fetch component READMEs from their repositories and merge all of them into a single C4. When a developer tries to understand a component, they would go to its diagram and view different aspects of it (some text, links to external API documentations, other sorts of diagrams, etc.).
I guess I need to start experimenting first to see if things work better than I expect. As you say, developers will not have huge problems once the workflow is in place.
I find keeping C4 diagrams in wikis often leads to them falling out of sync with the codebase. Ideally you’d keep the markup for the diagram in the relevant component repo and have a CI/CD process that keeps your diagrams up to date. I wrote a PlantUML Docker image for exactly that: https://github.com/robbell/plantuml-docker
Alternatively, Mermaid support is becoming more common—available in GitHub and Backstage TechDocs, and that allows you to embed diagrams in Markdown. Both PlantUML and Mermaid have support for linking to other diagrams I believe, and you could put your API definitions in your owning repos too using OpenAPI to keep everything together and in sync.
-
I’ve started using it a few months ago to visualize the current and proposed architecture of some subsystems. It takes a bit of time getting used to writing it but once you get the hang of it it’s a nice way to improve discussions. I’m not using Structurizr but rather PlantUML (and a C4 lib) as that integrates rather nicely with our Jira wiki.
It’s a nice tool in my toolbox, especially useful when talking about the bigger parts of the system. Nothing beats drawing some boxes and lines on the whiteboard for some quick conversations though.
Yeah for us, mermaid has been great to through in a documentation git repo and keep some consistencies. But 90% of the utility of a diagraming system is easily being able to draw something on a whiteboard with an almost empty marker and be halfway understood
With Structurizr, you get a site where you can click around to see different levels of the system and different views of of containers, components, etc. Is that also possible with the PlantUML library? Or do you only use it to document one part of the system independent of others? I kind of like the possibility to have the whole system in a single place so that if I change the name of component, it’s updated everywhere, but I don’t like that it’s its own thing separate from the wiki et al.
I’ve used C4 in different ways.
Using Structurizr Lite (docker): I do really like the “as code” aspect. The DSL is okay, the documentation of it not so much. But in the end, the tooling is too limited, and I’ve never come to terms with it. The diagrams becomes very locked in, and are cumbersome to export.
I’m not a fan of integrating SaaS solutions into the documentation workflow, but would really suggest that in favor of the Lite offering. Although I haven’t used it.
Using C4 with ordinary tools: What I’ve come to use more, is using the conepts (and templates when available) with other, non-specialized tools. With Miro for example (there are templates). While not as cool as the “as code” way, it’s an nice and accessible way of visualizing software systems.