Use when creating architecture diagrams with the D2 declarative diagramming language by Terrastruct. D2 offers advanced layout control, nested containers, scenarios, and multiple rendering engines.
USE FOR: architecture diagrams, system design diagrams, declarative diagramming, nested container diagrams, sequence diagrams, grid layouts, SQL table diagrams, scenario-based diagrams, diagrams requiring advanced layout control, D2 syntax, D2 CLI usage
DO NOT USE FOR: GitHub-native diagram rendering (use mermaidjs), C4 model diagrams (use c4-diagrams), UML specification compliance (use uml or plantuml)
license
MIT
metadata
{"displayName":"D2","author":"Tyler-R-Kendrick"}
compatibility
claude, copilot, cursor
references
[{"title":"D2 Language Documentation","url":"https://d2lang.com/"},{"title":"D2 — GitHub Repository (Terrastruct)","url":"https://github.com/terrastruct/d2"}]
D2 — Declarative Diagramming
Overview
D2 is a modern, declarative diagramming language created by Terrastruct. It compiles text into diagrams with support for multiple layout engines, nested containers, scenarios, layers, SQL table shapes, and advanced styling. D2 emphasizes readability, composability, and high-quality rendered output (SVG, PNG, PDF).
Basic Syntax
Shapes
Shapes are declared simply by naming them. D2 auto-creates shapes on first reference.
# Simple shapes
server
database
client
# Shape with label
server: Application Server
# Shape with explicit type
db: PostgreSQL {
shape: cylinder
}
# Multiple shapes on one line are not supported; declare each separately
Connections
Connections link shapes with arrows and optional labels.
client -> server: HTTP Request
server -> db: SQL Query
server -> client: HTTP Response
# Connection styles
a -> b: solid arrow
a -- b: line (no arrow)
a <-> b: bidirectional
a <- b: reverse arrow
Labels and Tooltips
server: Application Server {
tooltip: "Runs on port 8080"
}
server -> db: Reads data {
style.stroke: green
}
Shape Types
D2 supports a variety of built-in shapes.
Shape
Keyword
Description
Rectangle
shape: rectangle
Default shape
Square
shape: square
Equal-sided rectangle
Circle
shape: circle
Round shape
Oval
shape: oval
Ellipse
Diamond
shape: diamond
Decision / condition
Cylinder
shape: cylinder
Database
Queue
shape: queue
Message queue
Package
shape: package
Namespace / module
Page
shape: page
Document
Parallelogram
shape: parallelogram
Input/output
Hexagon
shape: hexagon
Prepare / process
Cloud
shape: cloud
Cloud / external service
Person
shape: person
Human actor
Class
shape: class
UML class box
SQL Table
shape: sql_table
Database table
Image
shape: image
Raster or SVG image
Text
shape: text
Plain text label
Code
shape: code
Code block
Containers and Nesting
D2 supports arbitrarily nested containers to represent hierarchical structure.
Grid layouts arrange child elements in a grid pattern.
services: Microservices {
grid-rows: 2
grid-columns: 3
grid-gap: 16
auth: Auth Service
users: User Service
orders: Order Service
payments: Payment Service
notifications: Notification Service
analytics: Analytics Service
}
Layers
Layers let you define multiple views within a single D2 file. Each layer produces a separate diagram.
# Base diagram (always rendered)
client -> server
server -> db
layers: {
detailed: {
client: Web Browser {
shape: rectangle
}
server: API Server {
auth: Auth Module
handler: Request Handler
auth -> handler
}
db: PostgreSQL {
shape: cylinder
}
client -> server.auth: "Authenticate"
server.handler -> db: "Query"
}
}
Scenarios
Scenarios show the same diagram in different states — useful for illustrating state changes or progressive disclosure.
server: Server {
style.fill: "#A3BE8C"
}
db: Database {
shape: cylinder
}
server -> db
scenarios: {
failure: {
server: Server {
style.fill: "#BF616A"
}
server -> db: "Connection Lost" {
style.stroke: red
style.stroke-dash: 5
}
}
recovery: {
server: Server {
style.fill: "#EBCB8B"
}
server -> db: "Reconnecting..." {
style.stroke: orange
style.animated: true
}
}
}
Sequence Diagrams
D2 supports sequence diagrams with its own syntax inside a shape: sequence_diagram container.
interaction: {
shape: sequence_diagram
user: User
api: API Server
db: Database
cache: Redis
user -> api: "POST /orders"
api -> cache: "Check inventory"
cache -> api: "In stock"
api -> db: "INSERT order"
db -> api: "order_id: 42"
api -> user: "201 Created"
}
Layout Engines
D2 supports multiple layout engines, each with different strengths.
Engine
Description
Best For
dagre
Default. Fast, hierarchical layout.
Most diagrams. Free and open source.
ELK
Eclipse Layout Kernel. More advanced algorithms.
Complex diagrams with many connections. Free and open source.
TALA
Terrastruct's proprietary engine. Best quality.
Presentation-quality diagrams. Requires license.
Specifying Layout Engine
# Via CLI flag
d2 --layout dagre input.d2 output.svg
d2 --layout elk input.d2 output.svg
d2 --layout tala input.d2 output.svg
Or in the D2 file:
direction: right
Direction
direction: right # left-to-right (default: down/top-to-bottom)
Available directions: up, down, left, right
CLI Commands
# Install D2
curl -fsSL https://d2lang.com/install.sh | sh
# Or via Homebrew
brew install d2
# Compile D2 to SVG (default)
d2 input.d2 output.svg
# Compile to PNG
d2 --format png input.d2 output.png
# Compile to PDF
d2 --format pdf input.d2 output.pdf
# Watch mode (auto-recompile on changes)
d2 --watch input.d2 output.svg
# Specify layout engine
d2 --layout elk input.d2 output.svg
# Specify theme
d2 --theme 200 input.d2 output.svg
# Dark theme
d2 --dark-theme 200 input.d2 output.svg
# List available themes
d2 --help# themes are numbered; see docs for full list# Render a specific layer or scenario
d2 --target "layers.detailed" input.d2 output.svg
# Sketch mode (hand-drawn look)
d2 --sketch input.d2 output.svg
# Pad output
d2 --pad 50 input.d2 output.svg
VS Code Extension
The official D2 extension for Visual Studio Code provides:
Syntax highlighting for .d2 files
Live preview panel (renders the diagram as you type)
Error diagnostics
Autocompletion for shape types, styles, and keywords
Install from the VS Code marketplace: search for "D2" by Terrastruct.
Use containers to represent system boundaries. Nesting shapes inside containers clearly communicates which components belong to which subsystem.
Define style classes for consistent visual language across the diagram. Create classes for services, datastores, external systems, etc.
Use the direction keyword to control the overall layout orientation. direction: right works well for data flow; direction: down works well for hierarchies.
Leverage layers for progressive detail. Use a base layer for the high-level overview and named layers for zoomed-in views.
Use scenarios to show state changes. Scenarios are ideal for showing normal operation vs. failure modes, or before/after states.
Choose the right layout engine. Start with dagre for simplicity. Switch to ELK for complex diagrams. Use TALA for presentation-quality output.
Use --watch during development. The watch mode auto-recompiles on save, giving you a live preview workflow.
Use --sketch for informal communication. The hand-drawn style signals that diagrams are conceptual, not final.
Keep .d2 files in version control. Like all diagrams-as-code, D2 files should live in the repository alongside the systems they describe.
Use SQL table shapes for data modeling. D2's sql_table shape with constraints is a concise way to document database schemas.
Reference icons from the Terrastruct icon set or use custom icon URLs for visual clarity in architecture diagrams.