We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Statically compile diagrams for blog posts in Markdown
2026-03-27 (updated: 2026-03-31) ・ elixir, side-project, blog, d2, mdex, markdown
Blog posts now support inline diagrams authored in D21.
Why D2
Like most people, I reached for Mermaid first. I didn’t want to add a JavaScript dependency though. D2 is a modern approach to diagrams, and has some nice things like supporting light and dark mode.
How it works
A custom MDEx2 pipeline plugin walks the document AST at compile time, finds every fenced code block tagged d2, and replaces it with a %MDEx.HtmlBlock containing the rendered SVG. Failures are raised at compile time.
Usage
A basic diagram:
Source
```d2
x -> y -> z
```
Diagrams support a few options in the info string. A border:
Source
```d2 border
client -> server -> database
```
Float layout, so text flows alongside the diagram:
Source
```d2 float=right border
web -> api -> db
```
The float=right option floats the diagram to the right and lets text flow alongside it. Use float=left to float it to the left instead. A clear div is needed after the flowing content to stop the wrap.
And collapsible diagrams using a native <details> element:
Diagram
Implementation
The plugin is a single file — lib/personal_site/mdex_d2.ex — attached in the markdown converter before calling MDEx.to_html!/1. The d2 binary is a prerequisite (installed via brew install d2 locally, and via the install script in CI)34.
You can see it in use in an existing post5.
Using codefence renderers
I learnt about MDExes new codefence renderer6 via the Thinking Elixier podcast7. It was a simple refactor8, to switch over to it.