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-regularwith 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.