188 comments

[ 1.8 ms ] story [ 231 ms ] thread
Short summary: "Making diagrams with a GUI didn't feel hard enough, so I do it with Haskell instead because Serious Computer Science"
i rebuked in horror when haskell was mentioned much like i rebuke in horror when vizio is mentioned. :)
I'd suggest evaluating tools on an as-needed basis, instead of wholesale rejection. And I'd 100% agree that the article could've benefited from a "Why Haskell, specifically" section. But really, few things are unequivocally useless. (Or good, for that matter)

(I'd also suggest that you meant 'recoiled', not 'rebuked')

The article has nothing to do with Haskell, other than it's what I use. Why should I have to justify that when I want to talk about architecture diagrams?

Would the same expectation be in place of my examples were in JavaScript? I doubt it.

It's your article, you don't have to justify anything.

That said, it still would've been nice to hear if Haskell has bought you anything that other languages don't do.

Would I have asked the same question for a JS article? Maybe I wouldn't have asked - I'm a bit more familiar with JS than I'm with Haskell - but a "and here's why I picked those tools" section would still have been interesting. I like hearing how people think about solving problems.

The fate of writing in public: people will always ask for more info on the parts that they're interested in.

I would question your experience with Visio if you don't even spell it correctly...
Architecture documentation is not just consumed by programmers/coders. I can't imagine showing Haskell (or something similar) to non-technical leadership or during an M&A process.

Know your audience. Frankly I would loath trying to decipher code when getting a high-level view of the architecture of a system during onboarding.

he suggested generating plantuml diagrams from it, so you would use the image for onboarding. you'd only see the code if you were going to update the architecture
TFA isn't advocating consuming architecture diagrams as code, but creating them with code. Render them and you get back the same images as you had before.
I don't often show architecture diagrams to non technical people BUT I also definitely don't show most technical people this Haskell code. I also don't show them the PlantUML.

I show them the png image.

Architecture-as-Code is source code. It can be compiled/rendered to other forms, like diagrams. (Ideally I'd like sonething like CSS to control styling the diagrams in so that you could adjust rendering, even selectively hiding pieces that aren’t interesting to a particular audience, without touching the logical description.)

In a perfect world, the architecture description would also be part of the “working” source code, interacting with more normal program code (and/or IAC) specifying the concrete components, and playing a concrete role in building and deploying systems, so that the work that goes into architecture specs isn’t duplicated and the arcuitecture description doesn’t get out of sync with reality.

One reason I prefer diagrams as "code" (by which I mean Mermaid or similar) is that they can be checked into version control, and changes can be reviewed over time. Unfortunately the diffs become less meaningful after significant changes.

Hmm.... outputting an image to highlight changes might be fun to hack together. One day :)

I feel like Jaeger and related tracing tools are basically this. I wish opentracing could go beyond rpc and into dbms guts and kernel internals.

Instead of looking at semi fictional assumptions of how services are tied together, you can follow the actual flow.

I love tracing as much as anybody, but that's most useful tracking between processes - when you can have boundaries within a single process too.

Having both - the diagram of what you expect and the diagram of reality - are useful.

FYI, tracing supports arbitrary spans at whatever level of granularity you want. However, out of the box auto-tracing is not going to do this, it depends on the language but usually the spans are at the RPC layer of abstraction, so any fine grained spans would be fully custom code.

We did this a while back for some critical functions in our rails monolith where we wanted to confirm that an expensive bit of code was behaving as expected. It’s not bad when the service is already set up with tracing libraries and the rest of the plumbing.

architecture diagrams change very infrequently, and are most useful in a given context (ie tailored to a particular viewer or team). writing actual code to describe them feels like a solution in search of a problem.
Agree, but I get the temptation if you want to be able to rapidly evolve your architecture early on to discover what works best.

Removing that extra bit of documentation related friction and maintenance that keeps an ill suited architecture around longer than it should or drifting from reality would be nice. I have a hard time seeing how the complexity or quirks of a diagramming tool that could also stay tailored to certain views wouldn’t become more of maintenance headache than being disciplined about manual diagrams.

Atlassian Marketplace's architecture diagrams change constantly. Altassian replaces a core system, we have to integrate with a new one, we rewrite or replace a system.

Did you read the part about generating diagrams from different things, e.g. service descriptors, service proxies, tests?

I am a solution architect who uses Lucidchart as well as automated arch docs like dependency cruiser and plantuml.

They both have value, and I will never give up custom diagramming.

It comes down to expression. Not everything in a diagram is purely informational, sometimes you need to represent concepts and relationships in ways that are very frustrating to encode in code

Yes this is something the article doesn't really address. Architecture diagrams are often not produced for technical people, or need to contextualise one domain for another.

Solution architecture is in one sense an art of communication; explaining systems and components for different audiences and contexts as clearly and efficiently as possible.

I find an automated display is fairly close to what you have through CMDB visualisation, just for engineers instead. They can be quite useful, but only for particular audiences.

This is exactly it. There isn't one authoritative way to project any process into a series of lines that is easily readable and conveys all ideas or dimensions. If there were, we wouldn't need the code in the first place. You'd just "draw the lines".
Here's another argument from last year: https://www.ilograph.com/blog/posts/its-time-to-drop-drag-an...

As for Haskell... while I think architecture diagrams should be written in code, they shouldn't be written in a programming language. Programming languages are for writing, well, programs. Programs execute, accept input, have state, and all manner of other things that just don't apply to diagrams. Diagramming in a programming language is just weird.

I didn't mention it, but I do write architecture diagrams which have input.

    data Version = Current | Future

    generate :: Version -> Diagram
Implementation uses a few if/else expressions. Really simple.

The final points of the post was that we should be able to generate architecture diagrams from other code. Parsing a service descriptor, generating them from tests, etc. You DO need a programming language.

Fair point, and an interesting distinction, I think. Diagramming from code vs. diagramming with code...
I’m always torn on this topic.

On the one hand, diagrams are easy to update, track changes, and show in different contexts.

On the other, a lot of automated diagrams are unclear because they miss important aspects of layout.

I believe you should start manual, and switch to code-based when it becomes painful to keep updating it.

That said, I don’t know why I’d do it in a bespoke system, as this article shows. That seems like the worst of both worlds.

Yes! we introduced mermaid for all our important repos.
Something I love about diagramming with a markup language is that you get to wipe your hands clean of tedious alignment and visual perfection. If you give me the ability to align and resize and do all kinds of cosmetic stuff to my diagrams, I will.
The industry spent a non-trivial time trying to maintain diagramming back in the waterfall days under UML and we really struggled to find a decisive solution.

As other posters have mentioned there are serious issues with having auto-generated and authoritative architecture diagrams. The biggest problems include maintenance burden (did you upgrade the diagrams?) and automating layout.

Personally I find the least ugly solution is to just draw some low-effort arrows and boxes when you need them and (for the most part) discard the diagram once you're done.

100% agreed. 90% of computer science/engineering related topics can be explained using annotated boxes and arrows. The thing is you have to have someone to explain them in english cause theyre as good as meaningless without context
Regarding layout, it seems that this is an area where AI could be useful. We’re probably lacking enough training data though.
I think simpler, manual solutions are underexplored.

The prevailing assumption is that you either do the layouting by hand (see: almost all diagramming tools with a GUI), let the computer do it for you as a starting point for manual layouting (see: aforementioned GUI tools that have "auto-layout" feature), or you don't do it at all, and let the algorithms handle it (Graphviz, PlantUML and other text-to-diagram tools). What I haven't seen anyone try is allowing manual hints and overrides in otherwise auto-layouted text-to-diagram context.

I'm pretty sure I discussed one proposal more thoroughly on HN, but I can't seem to find any of my comments on it other than this: https://news.ycombinator.com/item?id=19406739. To save you a click, here's the relevant bit:

  grid
    Comp1 Comp2 Comp3
          Comp4
    Comp5       Comp6
  endgrid
Imagine being able to write something like this in PlantUML, as a part of your normal diagram code. This is to be read as 2D arrangement, and would tell the layout engine how to place those particular elements relative to each other. The layout engine is then free to do whatever it normally does, but it must preserve the arrangement and alignment specified above.

Such a feature would solve more than half of the problems I have with automatic layouts. Additionally, pinning major elements like these would stabilize the diagram, avoiding the all too common situation when a slight modification to the current diagram (e.g adding or removing a single connection or node) flips the entire picture around.

I can think of other layouting hints, with varying levels of precision. They all stem from how I'd think about the diagram if I was doing it by hand (or in a GUI diagramming tool). These things go left-to-right in order; those things go to upper right corner, etc.

Mermaidjs supports css style sheets and hints which pretty much hits your target.
Maybe a hot take, but: If it’s simple enough to make an ASCII mock-up of.. making a diagram isn’t really adding value.
Note in particular that there is more than one view. If I'm looking at a subsystem I want the subsystems it depends on close. However in a larger view some of the subsystems it depends on will be spread far apart.
I didn't imply an ASCII mockup by my example. That grid is a way to declare, in form of self-depicting text, where the major components of the diagram go relative to each other. Imagine that every one of the components is a group, and each group contains half a dozen nodes, just as many arrows, and some may even have their own hierarchy.

The point is to pin major high-level parts of a complex diagram, so that as you continue to add, remove or modify the details, the rendered diagram doesn't look completely different every time you change something. This addresses my major issue with PlantUML, in that with any nontrivial diagram, even the tiniest change - such as adding or removing a link, or reordering neighboring nodes, can cause the diagram itself to completely flip, or spaghettify itself.

Yes! I use https://excalidraw.com/ for this. Its free and open source, is super easy to use, runs locally, looks nice without folks getting the impression it's a source of truth
i use draw.io myself. I'm not wholly wedded to any tool though.
I'm partial to yEd! as it is built on a graph model and has good automated layout options. Unfortunately not open source, but free to use for most applications.
With the nasty detail, that this is the issue that you now need on 2-3 levels someone having a good/perfect understanding of design. And having that after 5 years of maintenance is a challenge. Yes, there are also other problems then but just draw ad-hoc on demand (as much as I love it) is very dangerous.
The C4 model (https://c4model.com/) is great for architecture diagrams. You can use different tools to generate them. Here are the ones I've been using:

- https://github.com/plantuml-stdlib/C4-PlantUML - https://structurizr.com/ (by Simon Brown, the creator of the C4 model)

I've looked at mermaid & planetuml before. structurizr is new to me and looks interesting.

PlanetUML has the advantage of gitlab support, iirc -- allowing rendering of diagrams in README files. I'd like to see more options for that.

edit: interestingly, the author of structurizr (Simon Brown) was recently linked in another HN thread.

HN thread - https://news.ycombinator.com/item?id=34338995

YT link - https://www.youtube.com/watch?v=x2-rSnhpw0g

Can definitely recommend at least trying structurizr. I'd recommend starting with structurizr-lite, which runs locally on docker and version controlling your work as you go.

Just starting to use it myself to document an existing system that few people understand and there is not a lot of existing reliable knowledge of. Doing this sort of task has so many benefits long term but can be painful in terms of getting started.

The combination of C4 approach, structurizr for diagrams, embedded markdown for detailed notes and version control is feeling like a great combination.

Having it version controlled helps a lot with collaboration and communication. I'm using PRs in order to get insights and corrections from others without the need for constant meetings/discussions.

It's okay, for software architecture. Really you should just have lots of different types of diagrams until you have enough to understand the system. There's no single type or form that will suffice.
If you missed it, the article does talk about C4
1. Oh god yes. Anything to stop management by powerpoint.

2. But a piece of code written seperate and distinct from the actual code is just as disassociated from the real world.

3. So build the diagram from the actual code (parse the code in the repos, monitor real time network calls, put the data in the config files. whatever)

4. please for the love of god stop using low code solutions - they just make another huge hurdle to being able to introspect.

> Anything to stop management by powerpoint

I actually think Powerpoint would be a great format for software architecture.

Guiding the user through a coherent, step-by-step story rather than a mess of poorly related diagrams.

Man, I just was browsing around on Mastodon a couple weeks ago and found an architect that said he was using a tool for this sort of thing, and it was one I never heard of before and it looked like it was good. And now I can't find it again. All I remember is that it was text files that had a certain file extension of more than three letters.

At any rate, architecture diagrams are drawn in a lot of different contexts. I find myself reaching for these tools:

If I'm screen-sharing and want to draw something really quickly in a collaborative sense with others, I use Flying Logic. You can basically draw this as fast as you talk to each other. You could substitute that for any other drawing app that will automatically lay out as you draw. It basically runs a Sugiyama-type layered algorithm in a loop, and it supports groups and nesting. Sometimes I'll export these drawings into wikis, but it's more for a general sense - it's really just labeled boxes and arrows.

If I want to quickly put together something more detailed that will again be used only for reference, and not as a living document, I'll sketch something up in Excalidraw (free version) and export it. It still find it a little too fiddly for drawing live with an audience, but it has more flexibility than Flying Logic since you can also write text outside of the boxes and arrows.

But for stuff that needs to be more official and/or be edited, I'm all-in on the diagrams-as-text thing. I just haven't find the right tool yet. I feel like mermaid and plantuml are a venn diagram and haven't really committed to either. There's also that crazy python one that has all the AWS-branded diagram elements but it's too finicky to pull up quickly.

(comment deleted)
I have been using Excalidraw for both use cases 1 and 2 with (subjectively) great results. A few points to use it for live sketching:

* Having a consistent whiteboard orientation. In my area of work I deal with data pipelines. Sources are always on the left, consumers - always to the right * Only one or two types shapes should be used - to me, rectangle covers pretty much anything. A blackbox system? It's a square. Some logical domain? Rectangle. A specific interface? Maybe use a diamond or a circle. Excalidraw uses numbers for shortcuts, so those are always at the fingertips. * Colors should be kept to a minimum. 3-4 is plenty. Select a shape, "s" for the line color/"g" for fill color. * At the end of the day all systems exist to help humans. A human figure(stick one, from Excalidraw most downloaded libraries) should pretty much always be on the diagram.

I have found arch-diagrams-as-code tools do not allow me the freedom to emphasize important architecture bits the way I want them to.

My most successful tool for diagramming to date has been…Keynote of all things.

Yes, they will get out of date and stale, but they still serve the purpose as a communications tool.

And the tweaking they require for some more complex stuff means it might be actually quicker to draw it vs "code" it.

Even the most popular tools like PlantUML can't seem to figure out simple things like "do not draw text directly on the line"...

I've often found that diagrams as code is fine for simple things, but once the complexities start adding up, it becomes as much work maintaining the diagrams as it is to main the actual codebase. I honestly think there is little difference in effort required to maintain a diagram in something like draw.io over PlanetUML or ilograph. Time is just spent in different places

Automatically laying out diagrams in a away that makes contextual sense is one of those problems that seems easy, but is actually really hard. If it was easy, everyone would have used dot files and graphviz to generate their diagrams since the 90s

Disclosure: I'm the CTO at hava.io, where we automate cloud environment diagrams, so I'm biased towards automation

If your diagram is too complex to maintain as code it is too complex to read.

The diagram is not the kindgdom. And it will never be, that's why you see it is so difficult to generate them automatically from the real thing.

...If only we hadn't throw out all the tech writers along with the QA folks when moving to agile.

Really? A good example would be a chess board individual moves are easy to read in code (chess notation) a whole board state in the mid game not so much…
Depending on your chess engine (e.g. a physical board) a player could reasonably move many times without stopping to update the diagram. Maybe I forgot. Maybe I was in a hurry due to schedule problems. Maybe the diagram editor was offline for maintenance but the chess engine was still open so we kept on playing.

This might soon prove to be A Problem for folks who reasonably yet erroneously expected that each responsible player would of course update the diagram immediately after each move.

A chess game is over in at most about 60 moves. Sure the game might last for several hundred moves, but by move 60 only a few pieces are left and it is obvious [to experts] what is going to happen. Even in unlimited time controls, the actual time spent one all moves (as opposed to sleeping or doing some non-game activity while waiting for your opponent to move) isn't very long.

By contrast code lives for many decades. While it isn't all modified every day, it is changed often enough.

Yeah we need DiagramGPT on top to layout things the right way.
This is a problem with the languages, not a fundamental flaw. Well designed GUI can beat poorly designed language, but manipulating text has a much higher ceiling than drag and drop, in terms of speed and comfort/familiarity. Every programmer has their own ecosystem for manipulating text. I can grep, version control, diff, jump with Vim key bindings, search & replace, etc.

The layout engines are very hard. We've been making one [0] for over 2 years now. At first it seemed dubious whether it was possible to beat aesthetics of Graphviz, but we've been designing it to emulate how diagrams might look on a whiteboard drawn by humans. That's a very different heuristic than the theoretical hierarchical cross-minimizations that previous algorithms strive for, and it's yielded good results for a subset of diagrams. With further spot-assist of AI, this will only get better.

[0] not linked to not detract with self-promotion. you can find in my profile if you want

But text has two problems: end users hate it and people cannot see two pages of model/diagram-as-code vs. a visual diagram.

Not everyone is a developer.

That's like saying code has problems because end users hate it -- end users don't see it.
End users are consumers of the architecture here. Developers, testers, it, manager, customization specialists, customers, auditors,. ..
I think you might've misunderstood. The text generates a visual diagram. Like HTML generates a website. You're not showing customers the text, you show them the diagram. You don't show customers HTML, you show them the site.
Yeah you are right, i messed up. Indeed it is only the architect who will hate it :)
Thank you for mentioning the aesthetics in graphviz. It's not in any sense optimal; we chose a collection of heuristics meant to get somewhere close to diagrams made by hand (with tools). Some areas can clearly be improved. Even the initial ranking and cycle breaking is not always quite right. Possibly some of the middle stages need to be more aware of groups of nodes. How to draw sets of natural looking curves around obstacles in diagrams still seems to be an open problem, do we even know what to optimize? It's natural to ask if machine learning algorithms will get there first.
That's a horrible idea.

The problem is that people are munging architecture, data flow, and process into one diagram.

"Marketplace" isn't part of an architecture. "Commerce" isn't an architecture part. It's a functional piece.

Revamping how architecture diagrams are made won't fix incorrect ways of describing architecture.

Oh are you intimately familiar with Atlassian's systems?

Marketplace is Atlassian Marketplace, a real website, REST API and bunch of frontend components. If it's not part of an architecture, what is it?

I did simplify Commerce, the system is Atlassian Commerce Cloud Platform. I apologise that I simplified the name for an example, which has confused you.

I like the idea of "Contract-driven development", which should in principle help with this kind of thing. Services expose an API schema (say, OpenAPI), and other services can register usages of that contract.

This framework is usually intended to capture low-level collaboration between teams; if you need to make breaking changes to an API, you can see who's depending on it. But you can also in principle build a graph of interactions based on who is consuming contracts.

Another direction you can take this is to analyze traces from your production system, to determine who _actually_ calls who, instead of who claims to call who. I've not seen tools that offer this, though I know many of the big guys are doing this kind of analysis.

As far as the article goes -- I think all docs should be written in Markdown and checked in along-side the service/code that's being documented.

I've done diagrams in MermaidJS, but you can use fancier code tools and a Make script if you prefer. You can use something like Gitlab Pages to render your docs really easily. It's hard work maintaining the discipline to keep docs up to date, but at least keeping the docs next to your code you make it _possible_ to have a chain of PRs updating the documents at the same time, and a given release tag showing the docs changes associated with that release's code changes.

There's an important distinction between 2 categories in architecture diagrams:

1. Free-form. You have an image of what it should look like. It's precise. An algorithm won't be able to get it right.

2. Structured. You just want to represent the relationships in a clean way, and there's a hundred ways to do that acceptably.

Code/text can never replace the former, and free-form ones are always going to have its place. It's too black & white to say all diagrams should be code or not code.

I'm one the authors of a new text-to-diagram tool, and I wouldn't recommend it for all use cases. Example here of free-form vs structured: https://d2lang.com/tour/future#layouts

We made Terrastruct so you can mix-and-match both, with GUI or code: https://app.terrastruct.com/diagrams/2034296181

I totally agree the distinction exists, just wanted to say https://flowchart.fun/ is nice because you can run layout algorithms and then tweak to your liking w/in the same editor
I had been super excited by the work on d2 (and Tala), the new language for diagrams with automated layout. I'm happy to pay a reasonable price... but their prices are currently five times higher than the cost of a Visio subscription...

A pity, in my month long trial period I used it extensively, and loved it. Crawling back to Plant UML has been all the more painful for it.

I use (and like) D2, although it’s early days and still has a few rough edges. Prefer the syntax versus Mermaid.

It’s open source, though, isn’t it? You can just install locally with brew or whatever, plus the vscode extension and you’re off to the races. You don’t then get the fancy proprietary GUI, though - that’s what you’re referring to?

I'm referring to their layout engine, tala [1].

While there are other free layout engines, tala kicks ass.

There's just no separate pricing tier for people that want tala for use on the command line without the fancy proprietary GUI.

[1]: https://terrastruct.com/tala/

Thank you, feel free to email me, happy to discount for feedback.
Thanks! TIL. Will check it out. Dagre seems to have been okay for me, perhaps I don’t know what I’m missing.

UPDATE: Just tried out TALA. I'm in the same boat, interested only in the CLI. It definitely makes everything I've thrown at it look nicer. Would you be willing to expand a little on what you like about it versus Dagre, having had some experience with it?

You might want look into Strucurizr.

https://structurizr.com/

I've used it a bunch. It's pretty good! I think the Java API could use more types and less mutation but it works well.
Architecture is, literally, the blueprint that was used to build the building. But the blueprint is not the building. The building deviates from the blueprint, either by accident or by necessity.

Likewise, code is just the blueprint of the system. It is not the system. The system operates in its own unique fashion, and is often changing, even when the code isn't.

Therefore, things like Distributed Tracing and other Observability/Telemetry techniques can tell you a great deal more about what the system actually looks like as it exists in the world, not just on paper. This real world look at the system will help you reason about how it actually works.

But architectural diagrams are still necessary to plan work you haven't done yet. I really love the idea of asking everyone to draw their own diagram, because all those perspectives are valid, and you'll always find things that other people forgot about. Doesn't matter whether you make this drawing out of code or on a napkin. Do whatever best captures the work needed and gets you to the building phase with everything you need.

Three always-present perspectives: The system you think you have, the system you wish you had, and the system you actually have.
In actual building construction they have as-built plans, which are the blueprints made after the fact which should correspond to how the building was actually built.

I think it would be a good engineering practice to have the same in SW.

KeenWrite[0], the FOSS Markdown editor I’ve been working on, includes the ability to render plain text diagrams via Kroki[1]†. See the screenshots[2] for examples. Here’s a sample Markdown document that was typeset[3] using ConTeXt[4] (and an early version of the Solare[5] theme).

One reason I developed KeenWrite was to use variables inside of plain text diagrams. In the genealogy diagram, when any character name (that’s within the diagram) is updated, the diagram regenerates automatically. (The variables are defined in an external YAML file, allowing for integration with build pipelines.)

Version 3.x containerizes the typesetting system, which greatly simplifies the installation instructions that allow typesetting Markdown into PDF files. It also opens the door to moving Kroki into the container so that diagram descriptions aren’t pushed over the Internet to be rendered.

†Kroki, ergo KeenWrite, supports BlockDiag (BlockDiag, SeqDiag, ActDiag, NwDiag, PacketDiag, RackDiag), BPMN, Bytefield, C4 (with PlantUML), Ditaa, Erd, Excalidraw, GraphViz, Nomnoml, Pikchr, PlantUML, Structurizr, SvgBob, UMLet, Vega, Vega-Lite, and WaveDrom.

Note that Mermaid diagrams generate non-conforming SVG[6], so they don’t render outside of web browsers. There is work being done to address[7] this problem.

[0]: https://github.com/DaveJarvis/keenwrite

[1]: https://kroki.io/

[2]: https://github.com/DaveJarvis/keenwrite/blob/main/docs/scree...

[3]: https://pdfhost.io/v/4FeAGGasj_SepiSolar_Highlevel_Software_...

[4]: https://wiki.contextgarden.net/Main_Page

[5]: https://github.com/DaveJarvis/keenwrite-themes/

[6]: https://github.com/mermaid-js/mermaid/issues/2485

[7]: https://github.com/yuzutech/kroki/issues/1410

I've never seen people get value out of these diagrams, except when someone creates a one-off diagram to explain a particular detail when whiteboarding.

There are tools like this to generate diagrams of the relationships between database tables. They all seem to come with a way to filter down the number of tables displayed. A full diagram of complex databases actually appears harder to understand than a text version.

(comment deleted)