A skin with related guidance for generating C4 diagrams using the Plantuml and related tools.
Before you start, you need to be familiar at minimum with:
First of all you need to have a Plantuml editor up and running. For this you have multiple options (all of which will work with this):
- Local installation
- Free online editor (PlantText) <-- Online template ready for you to get started creating C4 models right now!!
- Free online editor from PlantUML <-- Another template, a click away, ready for you to get started creating C4 models right now!!
- VisualStudio Code Plugin: This plugin allows you to "embed" diagrams in your markdown files, which is the best of all worlds in my opinion, and hence really recommended.
Once you have something running (or just went to PlantText online editor), you can start using Plantuml to create text-driven models and diagrams.
Assuming that you have an environment that you can use Plantuml, add the following line:
!includeurl https://raw.githubusercontent.com/skleanthous/C4-PlantumlSkin/master/build/output/c4.puml
Just below @startuml
, and then use the following components with the specified stereotype:
C4 artifact | PlantUml | Stereotype for internal | Stereotype for external |
---|---|---|---|
Person | actor |
<<Internal>> |
<<External>> |
System | frame |
<<System>> , <<Internal System>> , or <<Internal>> |
<<External System>> or <<External>> |
System | rectangle |
<<System>> or <<Internal System>> |
<<External System>> |
Containers | component |
<<Container>> , <<Internal Container>> , or <<Internal>> |
<<External Container>> or <<External>> |
Containers | rectangle |
<<Container>> or <<Internal Container>> |
<<External Container>> |
Component | rectangle |
<<Component>> or <<Internal Component>> |
<<External Component>> |
Database | database |
<<Internal Database>> or <<Internal>> |
<<External Database>> or <<External>> |
Queue | queue |
<<Internal Queue>> or <<Internal>> |
<<External Queue>> or <<External>> |
Expanded systems, containers and components |
frame , component , or rectangle according to your need |
<Expanded> |
<Expanded> |
Reproduced (as closely as possible from diagrams from the official C4 model website)
-
System Context diagram
-
Container diagram
-
Component diagram
This project will help you use the awesome Plantuml tooling to create C4 diagrams for documenting architecture.
C4 defines a set of diagrams (core and supplementary) that are designed to document architecture in a way that is easy to understand and communicate.
Plantuml is a uniquely pleasant-to-use tool to create diagrams from text. The fact that this is a text-driven tool opens up a lot of previously impossible scenarios:
- It is a pleasure to edit
- You don't need special tooling
- You can keep your domain models side-by-side with your code
- You can embed models in your markdown documents in almost all major editors
- Did I mention that it is an absolute pleasure to work with Plantuml?
The only real disadvantage is that positioning can sometimes be a bit tricky.
This skin allows you to use stereotypes to skin your diagram to be close to what is standard with C4. You can use the !includeurl
to skin the following diagrams:
- System Context diagram
- Container diagram
- Component diagram
- System Landscape diagram
- Dynamic diagram
All that is needed to start is to add the following line:
!includeurl https://raw.githubusercontent.com/skleanthous/C4-PlantumlSkin/master/build/output/c4.puml
NOTE: The skin sets your diagram type as a Plantuml deployment diagram. If you want to add some incompatible artifacts in your diagram, you'll need to add the following statement after the
!includeurl
allowmixing
-
As mentioned above, the way the artifacts get C4 styling is through the use of Plantuml
<<stereotypes>>
. Currently stereotype names are not emitted; instead, a legend is emited at the bottom right. To turn it off, add!define NO_LEGEND
before the import, like in this example. -
There is support for two types of actors: Internal and external. The supported stereotypes are:
<<Internal>>
<<External>>
The following code:
@startuml !define NO_LEGEND !includeurl https://raw.githubusercontent.com/skleanthous/C4-PlantumlSkin/master/build/output/c4.puml actor Internal <<Internal>> actor External <<External>> actor InternalPerson <<Internal Person>> actor ExternalPerson <<External Person>> External -down-> Internal Internal -right-> InternalPerson InternalPerson -up-> ExternalPerson @enduml
Produces this outcome:
-
C4 Systems can be represented using Plantuml
rectangle
s andframe
s. In both cases the stereotypes that could be used are:NOTE: the simplicity of rectangles makes them really useful if you want to avoid the connotations implied by UML artifacts, so they are used to represent other C4 artifacts too
<<Internal System>>
<<System>>
(an alias to<<Internal System>>
)<<External System>>
The following code:
@startuml !define NO_LEGEND !includeurl https://raw.githubusercontent.com/skleanthous/C4-PlantumlSkin/master/build/output/c4.puml rectangle InternalRectangle <<Internal System>> rectangle ExternalRectangle <<External System>> frame InternalFrame <<System>> frame ExternalFrame <<External System>> interface InternalInterface <<System>> interface ExternalInterface <<External System>> InternalRectangle -right-> ExternalRectangle InternalFrame -right-> ExternalFrame InternalInterface -right-> ExternalInterface ' Positioning hints (down can be abbreviated to D etc) InternalRectangle -[hidden]down-> InternalFrame InternalFrame -[hidden]down-> InternalInterface ExternalFrame -[hidden]down-> ExternalInterface @enduml
Produces the outcome:
-
C4 containers can be represented by using plantuml rectangles (and not C4 components which is a bit confusing), which are useful to be shown normally on
System Context
,Container
andSystem Landscape
diagrams. The supported stereotypes are:<<Internal Container>>
<<Container>>
(an alias toInternal Container
)<<External Container>>
The following code:
@startuml !define NO_LEGEND !includeurl https://raw.githubusercontent.com/skleanthous/C4-PlantumlSkin/master/build/output/c4.puml component InternalComponent <<Internal Container>> component ExternalComponent <<External Container>> rectangle InternalRectangle <<Internal Container>> rectangle ExternalRectangle <<External Container>> interface InternalInterface <<Internal Container>> interface ExternalInterface <<External Container>> InternalComponent -right-> ExternalComponent InternalRectangle -right-> ExternalRectangle InternalInterface --right-> ExternalInterface ' Position hints (down can be abbreviated to D etc) InternalComponent -[hidden]down-> InternalRectangle InternalRectangle -[hidden]down-> InternalInterface ExternalRectangle -[hidden]down-> ExternalInterface @enduml
Produces this outcome:
-
C4 components can currently only be represented by Plantuml rectangles. The are only really useful in Component C4 diagrams, but obviously really important. The stereotypes used are:
<<Internal Component>>
<<Component>>
(an alias to<<Internal Component>>
)<<External Component>>
The following code:
@startuml !define NO_LEGEND !includeurl https://raw.githubusercontent.com/skleanthous/C4-PlantumlSkin/master/build/output/c4.puml rectangle Internal <<Internal Component>> rectangle External <<External Component>> interface Internal <<Internal Component>> as IInternal interface External <<External Component>> as IExternal Internal -right-> External IInternal -right-> IExternal 'Positioning hints Internal -[hidden]down-> IInternal External -[hidden]down-> IExternal @enduml
Produces this outcome:
-
The above should be enough to get you started. For more info please see:
- Complete examples
- Add skinning for C4 Code diagrams
- [2019-04-12] : Added skinning for sequence diagrams. Add
!define SKIN_SEQUENCE_DIAGRAM
before the include statement. See a short sample - [2019-03-29] : Added skinning to cloud. Either define "SKIN_CLOUD" or use
<<External>>
stereotype - [2019-03-28] : Added support to skin interfaces in systems, containers and components.
- [2019-03-28] : Fixed bug in legend titles
- [Initial release] : Skinning support for internal and external, systems, container, components and users. Includes skinning for databases and queues. Also, provides support for expanded items (see container diagram for an expanded system)
One major acknowledgment is C4-PlantUML from Ricardo Niepel. This is a very good library to work with C4, but I wanted something much more native to Plantuml. Specifically I wanted to be able to work with Plantuml native primitives (rectangle
, queue
, component
, etc.) instead of the "method"-like means that this library exposes.
Obviously a huge thank you to the awesome teams at PlantUML.
Finally, to Simon Brown for originating the C4 model.