terrastruct/d2
> A text-to-diagram language: you write declarative .d2 source, an auto-layout engine positions it, and D2 renders SVG/PNG/PDF.
GitHub repo · Official website · License: MPL-2.0
Overview
D2 is a diagram-as-code language and renderer written in Go, open-sourced by Terrastruct in November 20221. You describe nodes and connections in a compact declarative syntax (a -> b), and D2 handles layout, styling, and rendering to vector output. It competes in the same "diagrams from text" niche as Mermaid and PlantUML, but positions itself on layout quality, styling (themes, a hand-drawn "sketch" mode, animation) and a richer language (variables, imports, classes, globs). At roughly 24.7k stars and 703 forks, it is one of the more adopted entrants in this space, though smaller and younger than Mermaid's install base.
The defining tension is open-core. The language and renderer are MPL-2.0, and two layout engines (dagre and ELK) ship bundled and free. But the layout engine Terrastruct built specifically for software-architecture diagrams — TALA — is proprietary, a separate binary, and commercially licensed2. So the honest framing is: D2's free layouts are competitive with Mermaid's, but the layout that most justifies choosing D2 over alternatives is the one you pay for. Evaluate D2 on the bundled engines first, then decide whether TALA earns its price.
The second thing to know: unlike Mermaid, D2 does not render natively inside GitHub/GitLab/Notion markdown. It is a CLI/library you run in a build step. That makes it a docs-as-code tool, not a paste-in-a-fence tool, and shapes where it fits.
Getting Started
# Install (or use brew / go install oss.terrastruct.com/d2@latest)
curl -fsSL https://d2lang.com/install.sh | sh -s --
echo 'x -> y -> z' > in.d2
d2 --watch in.d2 out.svg # opens a browser, live-reloads on save
# in.d2 — containers, shapes, styled connections
server: {
api
db: {shape: cylinder}
api -> db: query
}
client -> server.api: request {style.stroke-dash: 3}
// D2 as a Go library — oss.terrastruct.com/d2
graph, _, _ := d2lib.Compile(ctx, "x -> y", nil, nil)
// then run layout + d2svg.Render to produce SVG bytes
Architecture / How It Works
The pipeline is: parse → compile → layout → render. The parser is error-tolerant — it recovers and reports multiple errors from one broken program rather than bailing on the first, which matters for editor tooling and large files3. Compilation resolves the language's higher-level features (variables, imports, classes, glob selectors, nested containers) into a flat graph of shapes and connections.
Layout is pluggable, and this is the core design decision. D2 does not compute positions itself; it delegates to a swappable layout engine:
- dagre — the default bundled engine, a JS layered-graph algorithm (Graphviz
DOT lineage) run via an embedded interpreter. Fast, good for hierarchical flows.
- ELK — bundled, from the Eclipse Layout Kernel family; better for
port-oriented, orthogonal, node-link diagrams. Often the better free choice for denser architecture diagrams.
- TALA — Terrastruct's proprietary engine, installed separately as a binary,
tuned for software-architecture aesthetics. Not open source2.
Rendering turns the laid-out graph into SVG. Themes are declarative palettes (theme-id), and "sketch" mode post-processes strokes into a hand-drawn look. Multi-board composition — layers, scenarios, and steps — lets one file define several related diagrams that D2 can emit as separate boards or an animated SVG. SVG is the native target; PNG and PDF are produced by rasterizing that SVG, a heavier path than plain SVG output4.
As a library, the Go packages under oss.terrastruct.com/d2 expose the same stages (d2lib.Compile, layout functions, d2svg.Render) so programs can generate diagrams from data — the common use case being architecture diagrams derived from infra/config.
Production Notes
- Layout is not stable across edits. Because positions are computed by the
layout engine, adding one node can reflow the whole diagram. Committing rendered SVGs to git produces large, noisy diffs. Commit the .d2 source and render in CI; treat the SVG as a build artifact.
- Engine choice changes everything. The same source under dagre vs ELK vs TALA
can look completely different. Pick an engine early (d2 --layout=elk) and pin it; switching late means re-reviewing every diagram.
- The best layout costs money. TALA is the reason many teams evaluate D2, and
it is proprietary and licensed. Budget for it or commit to living within dagre/ELK before standardizing on D2.
- Fonts. D2 ships only Source Sans Pro. Custom fonts require configuration and
embedding; expect glyph/spacing surprises with CJK or unusual character sets.
- PNG/PDF export is heavier. SVG is the first-class output. Rasterized formats
add cost and dependencies to the render step; prefer SVG where the consumer can display it.
- Language tooling is still maturing. As of the current README, D2 has an
autoformatter (d2 fmt), syntax highlighting, and a multi-error parser, but a full LSP was still a stated plan, not a shipped feature3. Editor support (VSCode, Vim, Zed, Emacs) exists but varies in depth.
- Non-Go bindings are community-maintained. First-class embedding is Go. The
JS/Python/C#/Java wrappers listed in the README are third-party and vary in freshness — verify maintenance before depending on one.
- License is weak copyleft. MPL-2.0 is file-level copyleft: fine to call the
CLI or link the library, but modifications to D2's own source files carry share-back obligations. Usually a non-issue for consumers; worth a glance for forkers.
When to Use / When Not
Use when:
- You want architecture/system diagrams as version-controlled text with real
auto-layout, rendered in a docs-as-code or CI pipeline.
- You've hit Mermaid's layout ceiling on dense diagrams and want ELK or TALA.
- You value styling (themes, sketch mode, animated multi-board diagrams) that
Mermaid doesn't offer.
- You generate diagrams programmatically from Go.
Avoid when:
- You need diagrams to render natively in GitHub/GitLab/Notion markdown with no
build step — Mermaid is the pragmatic choice.
- Simple flowcharts or sequence diagrams are all you need; the extra language
surface buys little.
- The layout you actually want is TALA and a proprietary/licensed dependency is a
dealbreaker.
- Your host language for programmatic generation isn't Go and you need mature,
supported bindings.
Alternatives
- mermaid-js/mermaid — use when you need native rendering inside GitHub, GitLab,
Notion, and most markdown surfaces with zero install.
- plantuml/plantuml — use when you need deep, mature UML (sequence/class/state) and
a JVM dependency is acceptable.
- excalidraw/excalidraw — use when you want freeform, hand-drawn diagrams edited
interactively rather than defined in text.
- structurizr/structurizr — use when C4-model software architecture is the
explicit goal and you want that opinionated workflow.
- kieler/elkjs — use when you only want the ELK layout engine itself to position a
graph you render yourself.
History
Exact per-version dates were not verified against the live changelog; milestones below reflect the project's public feature waves.
| Milestone | Date | Notes |
|---|---|---|
| Repo created | 2022-09-05 | Terrastruct begins the open-source D2 codebase5. |
| Public launch | 2022-11 | D2 open-sourced under MPL-2.0; dagre layout, SVG output1. |
| Layout + style waves | 2023 | ELK bundled, sketch mode, themes, TALA as separate engine. |
| Language features | 2024 | Variables, imports, globs, classes, grid layouts mature. |
| Steady releases | 2025–2026 | Ongoing; last master push 2026-04-24 at time of writing. |
References
- ^ D2 announcement / launch — Terrastruct, November 2022. https://terrastruct.com/blog/post/d2-a-new-diagram-scripting-language/
- ^ TALA layout engine (proprietary, separate binary). https://github.com/terrastruct/TALA
- ^ D2 README — "Language tooling" section (multi-error parser, autoformat, LSP planned). https://github.com/terrastruct/d2
- ^ D2 README — "Export file types" (SVG, PNG, PDF). https://github.com/terrastruct/d2
- ^ GitHub REST API — repos/terrastruct/d2 (stars, forks, license, dates), fetched 2026-07-15. https://api.github.com/repos/terrastruct/d2
Tags
go, diagrams, diagram-as-code, text-to-diagram, developer-tools, documentation, svg, software-architecture, cli, mpl-2.0