Jesse Claven

Jesse Claven

Jesse Claven

Jesse Claven


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
```
xyz

Diagrams support a few options in the info string. A border:

Source
```d2 border
client -> server -> database
```
clientserverdatabase

Float layout, so text flows alongside the diagram:

Source
```d2 float=right border
web -> api -> db
```
webapidb

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
authorposttag

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.

  1. D2

  2. MDEx

  3. feat(blog): Add statically compiled diagrams

  4. build: Use Docker over Railpack

  5. First shell command prediction model

  6. v0.11.6

  7. Thinking Elixir #295: Is Your Type System Leaking?

  8. refactor: Use MDExes new codefence renderers