getting-started/02-first-scene.md.
The problem with flat 2D for system diagrams
Flat 2D topology (d2, Mermaid, Graphviz, draw.io) is excellent for graph relationships: nodes, edges, hierarchies. It struggles with system shape:- All nodes occupy the same visual plane, so the reader has to infer “this is the edge, this is the data tier” from labels alone.
- Replicas and HA pairs flatten to “an edge with N”, losing the visceral sense that N instances exist.
- VPC / cluster boundaries become outlines — readable but forgettable.
What iso gives you
Isometric projection (the 2.5D view at ±30°) adds a controlled depth axis to a 2D canvas:- Layers separate naturally. Edge / mid-tier / data sit at different visual depths even without explicit grouping. The reader’s eye separates them in O(1) instead of by reading labels.
- Stacks express replicas. A pod stamped 3× tells you “this is replicated” without a label. Iso makes the stamping intuitive because each instance casts visible depth.
- Containers feel like containers. A translucent rounded slab wrapping its children reads as a region / VPC / cluster the same way a tray reads in a warehouse photo.
Why not just hand-author iso in Figma / FossFlow
Hand iso scales to about ten elements and zero people on the diff. Specifically:
The tradeoff: iso-topology gives up the freeform creativity of a
designer’s hand. You can’t paint custom textures or organic curves.
What you get is boring consistency and mechanical scale.
For one beautiful hero diagram, hire a designer. For an entire
docs site or an agent-generated architecture review, iso-topology
is the leverage.
Why a textual DSL specifically
Two reasons:Diffability
Architecture changes when the system changes. The DSL is the versioned record of intent — review it like you review code. SVG output is a derived artifact; commit it if you want, but the source of truth is the DSL.Generation
Most modern architecture diagrams should be generated, not drawn. From your infrastructure-as-code, from a service catalog, from a runtime topology snapshot, from an LLM that just read your design doc. iso-topology’s DSL is small enough that an LLM emits valid output zero-shot most of the time; for the rest,isotopo validate
closes the loop.
If you’re not generating diagrams today, you will be soon. The DSL
makes that path real.
The two-path design
We expose two textual paths intentionally:.d2 is the agent path. Agents understand graphs, not pixel
coordinates. Give them a graph language, let dagre/ELK position it,
let our translator project to iso.
.yaml is the designer / template path. You know exactly where each
element should sit (because the scene has a fixed template, or
because auto-layout produces something cramped). The DSL is more
verbose but pixel-precise.
Both produce the same Document model internally. Same renderer,
same output structure. You can mix:
- Start with
.d2, render, look at it - If layout’s wrong,
isotopo render scene.d2 ./out— the output copies the source astopology.d2 - Convert to
.yamlwhen you need to nudge specifics
Constraints we accept
A few honest tradeoffs:- No 3D perspective. This is true isometric, not 3-point projection. No vanishing point, no foreshortening. That’s the point — iso reads as iso, not as a poor camera angle.
- Limited shape vocabulary. 14 iso primitives (
capabilities.shapes), with 23 d2 source shapes mapped onto them. Polygons / custom paths require code changes (see../guides/extending.md). - No animations or interactivity. SVG output is static. If you
want hover states, post-process with CSS — every layer has a
data-layerattribute and every part hasdata-part.
Influences
- d2 — for the graph DSL surface and the dagre/ELK integration
- FossFlow — for the discoverability of iso as a diagram style
- Diátaxis — for thinking about docs as four flavors with different goals (this doc tree is structured that way)
- Compiler IRs — for the lowering pipeline metaphor (DSL → Document → ConvertOpts → SVG)