.d2 is the terrastruct/d2 graph
DSL. iso-topology accepts .d2 files as input and runs the d2
auto-layout pipeline, then translates the laid-out diagram into our
iso composite model.
Why this path exists: agents and code generators usually output
graph structure (nodes + edges), not pixel-precise layouts. The .d2
path lets them stay in their comfort zone and get an iso scene for
free.
For pixel-precise authoring, use the YAML path instead: DSL_YAML.md.
Quick example
topology.svg with all six elements iso-projected, dagre
auto-layout, an iso grid backdrop, and labeled connectors.
What translates and how
Shapes
ThemapD2Shape catalog turns every d2 shape string into an iso
shape plus a height multiplier. Discover the full list with:
Unknown d2 shape names fall back to
rectangle with the default
height. Skipping mapD2Shape is the right move for prototyping; you
can fill in better lowerings later without touching anything else.
Connections
d2 connections become isoConnector entries:
arrow: triangle and the label "query". Stroke
color and dash come from the d2 style (or theme defaults if neither
side specified one).
Nested containers → iso groups
d2 uses dot-notation OR brace-blocks to express containers:group per container level. The above produces:
- Kubernetes Cluster (outer translucent panel)
- Worker Node 1 (inner panel)
- LiteLLM Proxy + Cache (leaves)
- Ingress Controller (leaf)
- Worker Node 1 (inner panel)
- Users (sibling of Cluster)
Connector targets after nesting
Use the full dot-path:From/To keep the
full cluster.wn1.proxy1 id. Validation and the per-part output use
that same id space.
Layout engine
Both engines are built into the binary; no extra install needed.
What doesn’t translate (yet)
These d2 features are silently dropped or simplified:- Icons: d2’s
icon: <url>field is ignored. The iso primitive for the shape renders without an embedded image. - Shadow / 3D / multiple / double-border: d2 has these as visual modifiers; iso renders the base shape only.
- Image shapes: require an
icon:field; without one d2 itself rejects the source, so the case never reaches our translator. - Class / SQL Table rows: d2 paints them on the front face; iso
renders the rectangle envelope only (the row content is dropped).
Workaround: use the YAML path and set
content.rows: [...].
Inspecting the translation
out/topology.d2 is a copy of the source DSL (so re-rendering later
doesn’t need the original). Past that, the layout is opaque — d2
computes positions, we project them. If you need to debug layout,
run the standalone d2 CLI on the same .d2 file and inspect its 2D
output first.
Round-trip back to YAML
Each part also gets emitted as a per-part YAML fragment:isotopo render to get the standalone iso of just that
proxy. Useful for building icon libraries from a generated topology.
See OUTPUTS.md for the full output layout.