When maintaining documentation for a software project, you need to keep diagrams to describe everything. However, those diagrams will go out of date fast if they aren't easy to maintain. Rather than keep the raw diagram originals in a separate file, embedding diagrams inline using some other diagramming language (like dotviz) can make it easy to change the words and diagrams together and ease the maintenance burden. These days there are a lot of tools in this space. This post is an attempt to try out and compare these different tools strengths and weaknesses.
Criteria for Tool Selection
For this post, I'm specifically interested in tools that can integrate with the mdBook static site generators and enable the author to embed the diagram code inline with the markdown text. There are lots of other tools that allow authoring a diagram in code separately from your markdown, but I'm not interested in those for this post.
I've fallen in love with mdBook for general purpose documentation. There's basically nothing to configure and you get:
- a static site generator
- automatic, offline, fast search
- automatic reloading while writing & editors
- statically compiled binary
Additionally, mdBook supports plugins which can add in support for all kinds of goodies, not least diagrams as code inline in your markdown.
The Contenders: Diagram as Code Tools
Here's the top tools I'm considering:
Installation
preprocessor | binary size | compile time | precompiled | additional requirements |
---|---|---|---|---|
mdbook-plantuml | 5.8MB | 8m45s | windows | plantuml server/executable |
mdbook-mermaid | 4.3MB | 8m03s | yes | none |
mdbook-svgbob | 3.3MMB | 7m44s | no | none |
mdbook-graphviz | 2.5MB | 6m55s | no | graphviz |
These compile times are very unscientific. Some crates were downloaded from the network and others were cached locally. Don't read too much into that, except that if you're going to build your mdbook in a CI pipeline, you'll want to leverage the cache you don't need to recompile these dependencies on every run.
The winner here is mdbook-mermaid because one can forgo the compile time and simply download a pre-compiled binary from the Github releases page for a wide variety of platforms and because it doesn't require any additional install steps.
Mdbook-svgbob comes in second place over-all for compiling its image rendered inside itself, and not needing any other dependencies.
The PlantUML preprocessor is interesting because it can be configured to connect to a local or remote plantuml server. The advantage here would be if your team already has access to a plantuml server, you wouldn't need to set up the plantuml server yourself.
Improvements for Compile-Time & File Size
All four crates depend on clap
, serde
, pull-down-cmark
, pull-down-cmark-to-cmark
and mdbook
, mostly because this is the recommended approach in the mdbook user guide chapter on preprocessors:
By pulling in mdbook as a library, preprocessors can have access to the existing infrastructure for dealing with books... Then each chapter of the Book can be mutated in-place via Book::for_each_mut(), and then written to stdout with the serde_json crate... The pulldown-cmark crate implements a production-quality event-based Markdown parser, with the pulldown-cmark-to-cmark allowing you to translate events back into markdown text.
While these dependencies are high quality, there are some smaller crates that would suffice for this use case:
If mdbook itself exposed a small "core" crate that simply exported the Preprocessor
trait and other types, that might reduce the file-size/compilation time of all of these crates as well.
How Images Are Produced
preprocessor | format | when | separate files crated |
---|---|---|---|
mdbook-mermaid | svg | browser javascript | no |
mdbook-svgbob | svg | mdbook build | no |
mdbook-plantuml | svg or png | mdbook build | yes |
mdbook-graphviz | svg | mdbook build | yes |
From a setup and publishing point-of-view, mdbook-mermaid is probably in first place here. The rendered is simply copying your MermaidJS diagram from the code fence into a <pre class="mermaid">{}</pre>
html tag, and defering the SVG rendering until page load time. So, theoretically, this processor should have the smallest impact on mdbook build time. (Of course, this would make your readers page-load time worse, but that assumes anyone's reading your pages anyway!)
Having separate SVG files created is a slight win here. You can send someone a URL to this image, whereas if the image only exists inline with the HTML, its slighltly more difficult to get access to.
Breadth of Diagram Styles
preprocessor | styling | flow chart | graphs | sequence diagram | class diagram | cloud | SQL schema | shapes |
---|---|---|---|---|---|---|---|---|
mdbook-svgbob | yes | yes | yes | yes | probably | yes | probably | yes |
mdbook-mermaid | yes | yes | some | yes | yes | yes | yes | no |
mdbook-plantuml | yes | yes | ? | ? | yes | yes | yes | ? |
mdbook-graphviz | ? | yes | no | ? | yes | probably | yes | no? |
Honestly, this is just hard to compare. svgbob tries to infer outlines of shapes from ascii art, so it can create just about anything, but it requires the writer to be willing to play with random characters as an art medium, instead of as a rigidly defined illustration protocol. The big upshot of this is that even when the svgbob illustrations are viewed as plain text, they should convey the same impression. The downside is diagrams produced this way are likely much more time consuming to update and maintain.
MermaidJS seems to just steal whole swathes of syntax and semantics from graphviz, but offers just a subset of that functionality. Then it adds many other forms of visualization that I don't believe are part of graphviz (like pie charts). PlantUML is a newish dialect of UML designed to be used in documentation. It supports many different forms of visualization. Despite the code not looking much like the final image, graphviz, plantuml, and mermaid make it relatively easy to refactor your image by tweaking the code behind it compared to svgbob. If suddenly you need to add (or remove) a box from the middle of your diagram, or decide to start using squares everywhere, you'll have retype nearly the whole svgbob diagram -- but probably not for the others.
The mdbook-graphviz only supports the "dot" visualizations, so puts the plantuml and mermaid preprocessors ahead in this category.
Prettyness Factor
I have to say, the svgbob diagrams seem to be the most beautiful, and PlantUML to be the ugliest. Mermaid comes in second place to me based only my personal taste. YMMV.
svgbob diagrams
MermaidJS Sequence Diagram
GraphViz linux diagram
PlantUML sequence diagram
Ecosystem
Interestingly enough, PlantUML is implemented on top of GraphViz, which was released in 1991 by AT&T Labs. So, there's plenty of examples, tutorials, and chatrooms where you can find support for both of these tools.
Despite the rather meager search trends for MermaidJS compared to the top two, there have been two main contributors over the life of the project (since 2014) and there is a Gitter chatroom. Many developers have contributed tens of commits to the project over its life. Just in the last week, 16 pull requests were merged. Also, mermaidjs has an awesome live code editor you can play with. Highly recommend!
By comparison, svgbob really has only 1 developer (with about 10 others who've contributed a few commits a piece) and no activity in the last month. It might be tough to get support when you encounter rough edges here. Despite these worrying signs, there is a nice code editor here as well.
Conclusion
Personally, I'll be using MermaidJS with mdbook going forward, but I'll definitely play with svgbob as well!