name: d2 description: D2 (Declarative Diagramming) language reference — syntax for shapes, connections, containers, styling, SQL tables, sequence diagrams, UML classes. Load when working with D2 diagram code. license: MIT
d2 skill
D2 Language Reference
D2 is a declarative diagramming language that turns text into diagrams. It stands for Declarative Diagramming — describe what you want diagrammed, it generates the image.
Official Resources:
- Docs: https://d2lang.com
- Playground: https://play.d2lang.com
- Cheat Sheet: https://d2lang.com/tour/cheat-sheet/
Shapes
Basic Declaration
# Simple shape (default: rectangle)
shape_name
# Custom label
key: "Display Label"
# Multiple on one line (semicolon separated)
shape1; shape2; shape3
Shape Types
database.shape: cylinder
decision.shape: diamond
process.shape: hexagon
cloud_service.shape: cloud
user.shape: person
| Shape | Use Case |
|---|---|
rectangle |
Default, general purpose |
square |
1:1 ratio |
circle |
States, nodes (1:1) |
oval |
Start/end points |
diamond |
Decisions, conditions |
hexagon |
Processes |
cloud |
Cloud services |
cylinder |
Databases, storage |
person |
Users, actors |
parallelogram |
Input/output |
document |
Documents |
page |
Page shape |
queue |
Queue shape |
package |
Package shape |
step |
Step shape |
callout |
Speech bubble |
stored_data |
Data storage |
1:1 Ratio Shapes
circle and square maintain equal width and height.
Long labels will expand both dimensions.
Connections
Arrow Types
a -> b # Forward arrow
a <- b # Backward arrow
a -- b # Line (no arrow)
a <-> b # Bidirectional
Connection Labels
client -> server: "HTTP request"
database <- api: "query"
Chaining
a -> b -> c -> d
Repeated Connections
Repeated connections create new edges, they don't override:
Database -> S3: backup
Database -> S3: backup # Creates second edge
Cycles
Stage One -> Stage Two -> Stage Three -> Stage Four -> Stage One
Arrowheads
a -> b: {
source-arrowhead: {
shape: diamond
label: "start"
}
target-arrowhead: {
shape: arrow
label: "end"
}
}
Arrowhead shapes: triangle (default), arrow, diamond, circle, box,
cross, cf-one, cf-many
Containers (Nested Shapes)
Nested Syntax
Frontend: {
React App
Redux
}
Backend: {
API Layer
Services
}
Frontend -> Backend: HTTP
Container Labels
# Shorthand
clouds: Cloud Services
# Or using label keyword
clouds: {
label: Cloud Services
aws
gcloud
}
Reference Parent
Use _ to reference the parent container from inside:
christmas: {
presents -> _.birthdays.presents: regift
}
birthdays: {
presents
}
Direction
# Global direction
direction: right # up, down, left, right
Note: Per-container direction only works with TALA layout engine.
Styling
Style Block
component: {
style: {
fill: "#E3F2FD"
stroke: "#1976D2"
stroke-width: 2
stroke-dash: 3
opacity: 0.9
shadow: true
font-size: 14
font-color: "#333"
bold: true
italic: true
underline: true
border-radius: 5
}
}
Dot Notation
component.style.fill: "#4CAF50"
connection.style.animated: true
Special Objects
SQL Tables
users: {
shape: sql_table
id: int {constraint: primary_key}
name: varchar(255)
email: varchar(255) {constraint: unique}
role_id: int {constraint: foreign_key}
}
orders: {
shape: sql_table
id: int {constraint: primary_key}
user_id: int {constraint: foreign_key}
total: decimal
}
# Foreign key connection
users.id <-> orders.user_id: "has many"
Constraint shortcuts: primary_key → PK, foreign_key → FK, unique → UNQ
UML Classes
User: {
shape: class
+id: int
+name: string
-password: string
#internalField: string
+getEmail(): string
+setEmail(email: string): void
}
Visibility:
+ public, - private, # protected
Sequence Diagrams
api_flow: {
shape: sequence_diagram
client
server
database
client -> server: request
server -> database: query
database -> server: results
server -> client: response
}
Key rules:
- Order of definitions matters (appears in that order)
- Children share scope (same
alicethroughout) - Groups: containers with no connections but internal connections
- Spans: nested objects on actors
- Notes: nested objects with no connections
# Group example
Office chatter: {
shape: sequence_diagram
alice
bob
group: {
label: "awkward small talk"
alice -> bob: hi
bob -> alice: hello
}
}
Code Blocks
code_example: {
shape: code
language: typescript
content: |`
const response = await fetch('/api');
return response.json();
`|
}
Language aliases: md → markdown, tex → latex, js → javascript, go →
golang, py → python, ts → typescript
Markdown / Text
# Standalone markdown
description: |md
# Header
- Bullet point
- Another point
|
# Text shape (no markdown)
note: {
shape: text
label: "Plain text here"
}
LaTeX
formula: |latex
\frac{-b \pm \sqrt{b^2-4ac}}{2a}
|
Variables
vars: {
primary-color: "#4A90D9"
db-color: "#2ECC71"
}
database.style.fill: ${primary-color}
Layout Engines
| Engine | Best For | Command |
|---|---|---|
dagre |
General purpose, hierarchical | d2 --layout=dagre |
elk |
Complex graphs, better edge routing | d2 --layout=elk |
tala |
Software architecture, nested | d2 --layout=tala |
Engine-specific features:
nearto another object: TALA onlywidth/heighton containers: ELK only- Per-container direction: TALA only
top/leftpositioning: TALA only
Themes
# Apply theme by ID
d2 -t 101 input.d2 out.svg
# Theme ranges: 0-7, 101-104, 200-204, 300-303
CLI Reference
# Compile to SVG
d2 input.d2 output.svg
# Export formats
d2 input.d2 output.png
d2 input.d2 output.pdf
# Watch mode
d2 --watch input.d2 out.svg
# Format D2 file
d2 fmt input.d2
# List layouts
d2 layout
Common Patterns
Layered Architecture
direction: down
Presentation: {
UI Components
Views
}
Business: {
Services
Domain Logic
}
Data: {
Repositories
Database
}
Presentation -> Business
Business -> Data
Event-Driven System
Producer -> "Event Bus": Publish
"Event Bus" -> Consumer A: Subscribe
"Event Bus" -> Consumer B: Subscribe
"Event Bus".shape: parallelogram
Microservices
direction: right
Gateway: {shape: hexagon}
Auth Service: {style.fill: "#E3F2FD"}
User Service: {style.fill: "#FFF3E0"}
Order Service: {style.fill: "#FCE4EC"}
Gateway -> Auth Service
Gateway -> User Service
Gateway -> Order Service
Installation
# Install
curl -fsSL <https://d2lang.com/install.sh> | sh -s --
# Verify
d2 --version
# Uninstall
curl -fsSL <https://d2lang.com/install.sh> | sh -s -- --uninstall
Available Tools
When working with D2 in this environment, you have access to these tools:
d2_render
Render D2 code to an image file (SVG, PNG, or PDF).
// Render inline code
d2_render({ code: "a -> b: hello", format: "svg" });
// Render from file
d2_render({ file: "diagram.d2", format: "png" });
// With options
d2_render({
code: "...",
format: "svg",
theme: "dark", // default, dark, terminal, earth, cool, grape, asteroid, flagship
layout: "elk", // dagre, elk, tala
pad: 50, // padding in pixels (0-500)
returnBase64: true, // return base64 instead of saving to file
});
Parameters:
code- D2 diagram code (required if file not specified)file- Path to a .d2 file (required if code not specified)format- Output format:svg(default),png, orpdftheme- Visual theme:default,dark,terminal,earth,cool,grape,asteroid,flagshiplayout- Layout engine:dagre,elk, ortalapad- Padding around diagram in pixels (0-500)returnBase64- Return base64 encoded output instead of saving to file
Output: Saves to .output/ directory (e.g., .output/diagram.svg) unless
returnBase64: true
d2_check
Check if D2 CLI is available and get version information.
d2_check();
// Returns: { available: true, version: "0.6.0", ... }
d2_themes
List available D2 themes with descriptions.
d2_themes();
// Returns: { themes: [...], usage: "...", example: "..." }
d2_layouts
List available layout engines with pros/cons.
d2_layouts();
// Returns: { layouts: [...], usage: "...", example: "..." }
Workflow with Tools
- Check availability (optional):
d2_check() - Write D2 code using the syntax in this reference
- Render with
d2_render({ code: "...", format: "svg" }) - Iterate based on the output
Example Session
// Check D2 is installed
d2_check();
// Render a simple diagram
d2_render({
code: `
direction: right
User -> Server: Request
Server -> Database: Query
Database -> Server: Result
Server -> User: Response
`,
format: "svg",
theme: "dark",
});
// Output: .output/diagram-1234567890.svg
// Or return as base64 for immediate use
d2_render({
code: "a -> b",
returnBase64: true,
});
// Output: data:image/svg+xml;base64,...