The FC4 Framework

Posted by Avi Flax

Fig 1: screenshot of a Google Images search for “software diagram”

I love software architecture diagrams. Good examples harness the strengths of both linguistic and visual communication to reach pinnacles of precision, clarity, and richness. I even love bad diagrams — which is most of them — for the earnest optimism they convey, that this medium of entities, labels, relationships, and composition has some magical ability to convey the Truth.

I love making architecture diagrams too. I love almost everything about it — the creativity, the research, the work of naming and composing the elements, even styling.

But then there are the tools.

Fig 2: screenshot of a diagramming tool Fig 3: screenshot of a diagramming tool Fig 4: screenshot of a diagramming tool Fig 5: screenshot of a diagramming tool Fig 6: screenshot of a diagramming tool

I’ve been perpetually dissatisfied by diagramming tools for years, for a bunch of reasons:

Most of them:

  • Are GUI-driven and therefore fiddly
    • I’ve spent many hours fiddling with diagrams to get all the elements aligned just so. It was all a poor use of my time.
  • Use proprietary binary file formats that encode the graphics as graphics
  • Support no textual representation of diagrams
  • Lack a comprehensive, opinionated, conceptual model of how to approach software diagramming

All these dissatisfactions but the first are rooted in my drive to scale this work beyond myself, beyond individual authorship. I want to collaborate with my colleagues on these diagrams, in depth and over time. I want this work to have lasting value and impact beyond the contributions and tenure of any individual.

As software designers and developers, we already have rich, robust tools and workflows to facilitate and support collaboration via files: version control systems (VCSs) such as Git and Mercurial and collaboration systems built on those VCSs such as GitHub, GitLab, BitBucket, etc. These systems, however, are optimized for collaborating on text files; because most diagramming tools use binary file formats and support no textual representation of diagrams it’s challenging and awkward to collaborate on such diagrams using most popular version control systems.

The few tools that do have a textual representation and a command-driven rendering process — the most prominent being Graphviz — have never felt like a good fit for diagramming software architectures. Graphviz, for example, being focused on graphs, makes composition and nesting quite awkward, and supports only algorithmic layout when rendering diagrams, making it very difficult to tell a coherent story with the relative positioning of elements. Whenever I tried Graphviz, I’d find myself wrestling with its algorithms just to get things laid out clearly and usefully.

Then there’s the lack of a conceptual model for how to author architecture diagrams. Without this, it’s extremely inefficient to onboard new collaborators — the implicit model needs to be described during in-person training sessions during which the more experienced authors attempt to extricate implicit rules and guidance from their fingertips, implicit knowledge that’s developed with time and is hard to transfer.

This is not a criticism of any of these diagramming tools for not meeting my requirements. They’re general-purpose diagramming tools, and general-purpose tools have plenty of value. It’s just that, by definition, such general-purpose tools are not optimized for my specific needs.

Despite my dissatisfaction with every diagramming tool I’d ever used, whenever the time came to create a new corpus of diagrams, I’d always try and fail to find a newer and better tool. So with a sigh and slumped shoulders I’d resign myself to using one of the GUI tools.

So when I joined Funding Circle in October 2017 and observed that we needed some big-picture architecture diagrams of all our systems, I tried a bunch of different tools — OmniGraffle, LucidChart, Graphviz, Keynote, and even HTML+CSS. But I remained dissatisfied with all of them.

Then, just as I was on the cusp of proceeding resignedly with one of the usual suspects, I stumbled across Simon Brown’s C4 Model for Software Architecture and the tools he created to support it, Structurizr and Structurizr Express — and I was delighted. As I read the docs, played with the tools, and watched some of Brown’s talks I felt a growing frisson of recognition. Brown and I had observed many of the same problems with the approach and tools commonly employed to create software architecture diagrams — but he had done something about it, something substantial and impressive. Although Brown and I had never spoken nor corresponded, I felt a powerful kinship with him and his work.

Brown recently wrote an excellent introduction to the C4 model in which he states:

C4 stands for context, containers, components, and code — a set of hierarchical diagrams that you can use to describe your software architecture at different zoom levels, each useful for different audiences. Think of it as Google Maps for your code.

To create these maps of your code, you first need a common set of abstractions to create a ubiquitous language to use to describe the static structure of a software system. The C4 model considers the static structures of a software system in terms of containers (applications, data stores, microservices, etc.), components, and code. It also considers the people who use the software systems that we build.

I wrote above that a major problem with all diagramming tools I’ve used to create architecture diagrams is that they lack a comprehensive and opinionated conceptual model of how to approach software architecture diagramming.

Well, that’s exactly what C4 is. Brown recognized this need and also realized that this model would be most useful if it were abstract — independent any particular implementation or toolset. That’s why, I surmise, he gave it a name and its own identity, independent of the tools he created to support it. Just about any diagramming tool can be used to create C4 diagrams, so anyone can create C4 diagrams with the tools with which they’re already comfortable or perhaps required to use.

The C4 model alone is impressive and extremely promising, but Brown didn’t stop there. He also created Structurizr, a commercial Web app for authoring, editing, hosting, publishing, and viewing C4 diagrams. Structurizr is available as a hosted service or for on-premises installations.

Structurizr has a free plan that’s quite useful, but Brown also released Structurizr Express, a single-page Web app that allows you to create a single standalone C4 diagram by defining it as text.

Just to explain that distinction a bit: Structurizr hosts workspaces; each workspace is intended to host a full model of your software ecosystem — all the systems, components, containers, people, and all the relationships between them — and a set of views “over” those elements. Those models and views are supposed to be defined and populated programmatically via code.

Brown has published a cogent overview of why Structurizr encourages you to use code as a way to create software architecture models. But when I decided to try out the C4 model, I chose to start with Structurizr Express and its data-driven approach. It seemed simpler and easier, and jived with my enthusiasm for functional programming, which, as per Dmitri Sotnikov “…brings data to the forefront and it encourages us to think about our problems in terms of data transformations.”

In mid-December 2017 I created my first C4 diagram: a System Landscape diagram of Funding Circle’s UK platform. My initial impressions of C4 and Structurizr Express were very positive.

Here’s a blurry export of that diagram:

Fig 7: blurred version of our UK System Landscape Diagram

I had only one quibble: whenever I would paste my diagram’s source YAML into Structurizr Express in order to edit the diagram graphically, Structurizr Express would regenerate the YAML and make it, to be blunt, very ugly.

For example, this is a clean YAML representation of a contrived System Landscape diagram:

type: System Landscape
scope: Acme inc.
description: Big-picture diagram showing all our systems.

- type: Person
  name: A
  tags: foo, bar
  position: '125,50'
- type: Software System
  name: B
  position: '800,100'

- source: A
  description: interacts with
  destination: B

- type: element
  tag: Person
  shape: Person

size: A6_Landscape

And here’s what that same diagram looks like after it’s been edited with Structurizr Express:

    type: Person
    name: A
    description: ""
    tags: 'foo, bar'
    position: '125,50'
    type: 'Software System'
    name: B
    description: ""
    tags: ""
    position: '800,100'
    containers: []
    source: A
    description: 'interacts with'
    technology: ""
    destination: B
    tags: ""
    type: element
    tag: Person
    width: ""
    height: ""
    background: ""
    color: ""
    border: ""
    opacity: ""
    fontSize: ""
    shape: Person
    metadata: ""
    description: ""
type: 'System Landscape'
scope: 'Acme inc.'
description: 'Big-picture diagram showing all our systems.'
size: A6_Landscape

As you can see, Structurizr Express adds all missing properties to each object, even those that are optional and have empty/blank default values. It also reorders the root entries and wraps extraneous quotes around most strings. I find the second example ugly and hard to read.

Aside from this one thorn in my side, I was enjoying Structurizr Express and wanted to keep using it. Luckily, I’m a software developer, so it occurred to me that I might be able to solve this problem for myself, with code. So I opened up my terminal and whipped up a little tool to clean up and reorder Structurizr Express YAML documents. I called it Restructurizr.

With the addition of Restructurizr I had all the ingredients I needed to really dig in and get to know the C4 Model and Structurizr Express, by creating the diagrams we needed within Funding Circle.

As I did so, I realized that Restructurizr provided an additional benefit: it made peer review of the diagram source more viable. Making the YAML documents smaller, giving them simpler, more consistent formatting, and a stable sort (of both properties and values) meant that diffs were nearly guaranteed to show only meaningful differences. As anyone who’s ever had to review a noisy diff knows, the added noise can really slow down review and make it plain annoying. I was excited when I realized this; I find enabling and supporting collaboration to be compelling and fulfilling.

As I used C4, Structurizr Express, and Restructurizr in collaboration with my coworkers to create, edit, review, revise, and publish software architecture diagrams, I also worked to share what we were up to more broadly across Product Engineering. I wanted to encourage more folks to create and publish diagrams, both because we needed them and to elicit feedback on the approach and the tools.

As more people started using the model and tools it became clear that we needed to document guidance and guidelines on using them. As comprehensive as C4 and Structurizr Express are, they’re still somewhat general; any organization or team that adopts them will need to make and document some shared decisions as to semantics, workflow, etc. So we started documenting all that in our internal wiki. Over just a month or two, the guidance and guidelines became so comprehensive and thorough that I started to think of them as a methodology.

Then one day I found myself at my synagogue’s kiddush, enthusiastically explaining to my friend Ilan what I was working on. When he said he’d love to check it out and maybe give it a try, I got real excited, and thought — hell yeah, why shouldn’t this all be FLOSS‽ None of it is specific to Funding Circle, so it didn’t need to be proprietary. My only hesitation, I told Ilan, was that I wasn’t sure how to describe it all. I had a methodology and a tool, built on a conceptual model (C4) and another tool (Structurizr Express) — that was all quite a mouthful. Luckily Ilan is smarter than me — he immediately said something like “a methodology plus a tool — sounds like a framework to me.” I love that guy.

Now that I had a term to describe this thing, it lacked only a name before I could unleash it on the world. Being the lazy geek that I am, and wanting to reference the C4 model, I decided to combine FC (for Funding Circle) and C4 into FC4. (I actually considered FC²4/FC24 but my colleagues thankfully talked me out of it.) Thus was named the FC4 Framework, which I first released on 9 March 2018.

Since then we’ve seen steadily increasing interest and adoption of FC4 within Funding Circle, and even a little elsewhere. We’ve continued to refine and improve the framework and we don’t see that stopping any time soon — we see many opportunities to level it up significantly, such as a linting feature, automated rendering, a streamlined workflow, and possibly a new data scheme that’d decouple the static models of software systems and the views of those models.

If you have a chance to give FC4 a try, please let us know what you think!