DEV Community

Brian Onang'o
Brian Onang'o

Posted on • Updated on

Using Github and MermaidJs to Document Software Architecture Using C4 Model

UML is a popular standard for developing software architecture. But it has an alternative in thee C4 model. The C4 model is an "abstraction-first" approach to diagramming software architecture, based upon abstractions that reflect how software architects and developers think about and build software. For more information about the C4 model, please visit its website.

The C4 model consists of hierarchical diagrams in 4 steps:

  1. The System Context Diagram
  2. Container Diagram showing the independently deployable parts of the sytem.
  3. Components of the containers
  4. Code

More information is made available as we go down the hierarchy, more like zooming into a map. To be able to visualize C4 models, we have to have a system that is able to take us from one item up in the hierarchy to its children down the hierarchy. There are not that many tools that are able to work with C4 models yet, these being limited to:

  1. Gaphor. This is a free desktop application
  2. C4-plantuml which provides a VS-Code extension
  3. goadesign for creating software architecture models and diagrams in Go
  4. structurizr which is proprietary software from Simon Brown, the developer of the C4 model.
  5. MermaidJs, which is free and can be used in github markdown files.

We are going to show how to build simple models using mermaid JS, with an example available at mermaid-c4-model

Using mermaid in a github md file

Include a code section with mermaid as the language:

```mermaid
% mermaid code goes here
Enter fullscreen mode Exit fullscreen mode

Choosing Diagram type

Mermaid supports a number of diagram types. We will use flowchart TB for our C4 model diagrams.





```mermaid
flowchart TB
% the rest of mermaid code goes here
Enter fullscreen mode Exit fullscreen mode

Using Subgraphs

MermaidJs was not intended for building diagrams with a lot of information as in the detailed C4 model diagrams.
User Diagram
Consider the user diagram for example. We cannot possibly include all that info in a single mermaid object. So we choose subgraphs as our basic units. We will still not be able to get the icons into the subgraphs. But they are not absolutely necessary.

To build the user diagram above in mermaid, we use a subgraph and 2 other objects (A1 and B1) inside the subgraph. The subgraph and A1 have the same color applied to them. B1 can retain have the default object color.

% color definition
classDef gray fill:#62524F, color:#fff
subgraph publicUser[ ]
    A1[[Public User<br/> Via REST API]]
    B1[Backend Services/<br/>frontend services]
end
% Apply the color to subgraph and A1
class publicUser,A1 gray
Enter fullscreen mode Exit fullscreen mode

The result is:
userDiagramMermaid

Each subgraph representing a single object has an Ai and a Bi object. Where i is the number of the subgraph. When applying a color or any other style, we apply it to both the subgraph and the Ai object.

Using Legends

A different mermaid object is used to create the legend. A subgraph holds different objects having different colors applied representing the different types of elements in the model, with a description in the object text. For example, the legend below is created using the following code:

Legend Example

flowchart TB
classDef borderless stroke-width:0px
classDef darkBlue fill:#00008B, color:#fff
classDef brightBlue fill:#6082B6, color:#fff
classDef gray fill:#62524F, color:#fff
classDef gray2 fill:#4F625B, color:#fff

subgraph Legend[Legend]
    Legend1[person]
    Legend2[system]
    Legend3[external person]
    Legend4[external system]
end
class Legend1 darkBlue
class Legend2 brightBlue
class Legend3 gray
class Legend4 gray2
Enter fullscreen mode Exit fullscreen mode

Opening Container Diagrams from Context Diagram and going further down the hierarchy

To open a container diagram, we implement a click event handler on the object representing the system having the container diagram. In the following example, the Books system has a container diagram representing more detailed info about the system.
Context Diagram
To open the container diagram, we implement:

subgraph booksSystem[ ]
    A3[[Books System]]
    B3[Allows interacting with book records]
end
class booksSystem,A3 brightBlue

click A3 "/csymapp/mermaid-c4-model/blob/master/containerDiagram.md" "booksSystem"
Enter fullscreen mode Exit fullscreen mode

The click event does not work with subgraphs. That is why we use A3 instead of booksSystem.
The url supplied has to be either absolute pointing to the container diagram, or relative to 'https://github.com'. It seems that we cannot supply a path relative to our repo yet. This means that if this repo is forked, then the path has to be editted to reflect its new location.

The same is done for opening a component diagram from a container diagram.

Since the click event is on the A node inside the subgraph, we have to be sure to click on it, rather than on the subgraph itself.

A little issue

For large models, github seems not to have a way of scaling it up so that the text and other objects are visible. Zooming in the page does not zoom in the iframe rendering the svg.

All in all, its a wonderful way to start documenting simple software architectures.

The full example is available in this github repo.

The C4 model is pretty easy to use, so start designing your software in a way that you can share your design with others.

Top comments (0)