Share a D2 diagram

D2 exists because architecture diagrams rot. The text file lives next to the code, d2 fmt keeps it tidy, and the layout engine does the part humans are bad at. Then somebody has to actually look at it — and the diagram goes into Slack as a PNG, where the link: on the auth service goes nowhere and the tooltip: explaining why the queue is there does not exist.

The export is not the diagram. It is a photograph of the diagram.

Render to SVG, not PNG

d2 --theme=200 --sketch arch.d2 arch.svg

SVG is the format that keeps D2's interactive attributes:

  • link: https://… on a shape stays clickable.
  • tooltip: "…" still shows on hover.
  • Text stays text — selectable, searchable, and legible at any zoom, which is the whole reason a 40-node system diagram is readable at all.

PNG discards all three. So does a screenshot, and so does pasting the image into a doc.

Wrap it and publish

Comma's report body is an HTML document, so give the SVG one:

d2 arch.d2 arch.svg
printf '<!doctype html><meta charset="utf-8"><title>Architecture</title>\n' > arch.html
cat arch.svg >> arch.html

Drop arch.html into the app, or PATCH it from CI so the link never goes stale:

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html arch.html \
        --arg t "Platform architecture — $(git rev-parse --short HEAD)" \
        '{title: $t, html: $html}')"

Inlining the SVG matters: referenced as <img src="arch.svg"> the browser renders it in image mode, where links and tooltips are inert by spec. Inline, it is part of the document and behaves.

Animation and multiple boards

D2's board syntax describes a sequence — the system before the migration, then during, then after — and one flag turns it into a single animated file:

d2 --animate-interval=1200 migration.d2 migration.svg

That is one SVG containing every board. It is also the export that suffers most from being flattened: a PNG of it is board one, and board one is the state everyone already understands.

The diagram is where the argument happens

An architecture diagram is posted to start a discussion, and the discussion immediately leaves it. Comments anchored to the rendered diagram keep the objection on the thing being objected to — see commenting on HTML.

Regenerate from the .d2 file on merge and PATCH the same report id: every publish appends a revision, so the URL always shows current architecture and the revision history shows when the shape of the system changed and who asked why.

Who can see it

Per report: private, your team, anyone signed in at your domain, or anyone with the link. An internal topology is not a public artifact — see sharing & access control.

Limits

  • Entry HTML: 5 MB. A large D2 SVG with an embedded font can approach that; --font-regular with a subset, or dropping --sketch, cuts it sharply.
  • Assets: 25 MB per file, 250 MB and 500 files total.
  • Scripts run, sandboxed — no same-origin access.
  • 60 requests/minute per token.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish a diagram →

Related