AgentSkillsCN

d2

适用于使用 Terrastruct 的 D2 声明式绘图语言来创建架构图。D2 提供了高级布局控制、嵌套容器、场景以及多种渲染引擎。 适用场景:架构图、系统设计图、声明式绘图、嵌套容器图、序列图、网格布局、SQL 表格图、基于场景的图表、需要高级布局控制的图表、D2 语法、D2 CLI 使用。 不适用场景:GitHub 原生的图表渲染(应使用 Mermaid.js)、C4 模型图(应使用 C4 图)、UML 规范的合规性(应使用 UML 或 PlantUML)。

SKILL.md
--- frontmatter
name: d2
description: |
    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

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.

d2
# 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.

d2
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

d2
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.

ShapeKeywordDescription
Rectangleshape: rectangleDefault shape
Squareshape: squareEqual-sided rectangle
Circleshape: circleRound shape
Ovalshape: ovalEllipse
Diamondshape: diamondDecision / condition
Cylindershape: cylinderDatabase
Queueshape: queueMessage queue
Packageshape: packageNamespace / module
Pageshape: pageDocument
Parallelogramshape: parallelogramInput/output
Hexagonshape: hexagonPrepare / process
Cloudshape: cloudCloud / external service
Personshape: personHuman actor
Classshape: classUML class box
SQL Tableshape: sql_tableDatabase table
Imageshape: imageRaster or SVG image
Textshape: textPlain text label
Codeshape: codeCode block

Containers and Nesting

D2 supports arbitrarily nested containers to represent hierarchical structure.

d2
aws: AWS Cloud {
  vpc: VPC {
    subnet_a: Subnet A {
      api: API Server {
        shape: rectangle
      }
      worker: Background Worker {
        shape: rectangle
      }
    }
    subnet_b: Subnet B {
      db: PostgreSQL {
        shape: cylinder
      }
      cache: Redis {
        shape: cylinder
      }
    }
  }
  cdn: CloudFront {
    shape: cloud
  }
}

user: User {
  shape: person
}

user -> aws.cdn: HTTPS
aws.cdn -> aws.vpc.subnet_a.api: Forward
aws.vpc.subnet_a.api -> aws.vpc.subnet_b.db: SQL
aws.vpc.subnet_a.api -> aws.vpc.subnet_b.cache: Redis Protocol
aws.vpc.subnet_a.worker -> aws.vpc.subnet_b.db: SQL

SQL Tables

D2 has first-class support for SQL table shapes with columns, types, and constraints.

d2
users: Users {
  shape: sql_table
  id: int {constraint: primary_key}
  email: varchar(255) {constraint: unique}
  name: varchar(100)
  created_at: timestamp
  org_id: int {constraint: foreign_key}
}

organizations: Organizations {
  shape: sql_table
  id: int {constraint: primary_key}
  name: varchar(100)
  plan: varchar(50)
}

orders: Orders {
  shape: sql_table
  id: int {constraint: primary_key}
  user_id: int {constraint: foreign_key}
  total: decimal(10,2)
  status: varchar(20)
  created_at: timestamp
}

users.org_id -> organizations.id
orders.user_id -> users.id

UML Class Shapes

d2
UserService: UserService {
  shape: class
  -connection: DBConnection
  -cache: RedisClient
  +getUser(id int): User
  +createUser(data UserDTO): User
  +deleteUser(id int): bool
  -validateEmail(email string): bool
}

UserRepository: UserRepository {
  shape: class
  -db: DBConnection
  +findById(id int): User
  +save(user User): User
  +delete(id int): void
}

UserService -> UserRepository: uses

Styles

Shape Styles

d2
server: Application Server {
  style: {
    fill: "#4C566A"
    stroke: "#D8DEE9"
    font-color: "#ECEFF4"
    border-radius: 8
    shadow: true
    opacity: 1.0
    stroke-width: 2
    stroke-dash: 0
  }
}

Connection Styles

d2
a -> b: Request {
  style: {
    stroke: "#88C0D0"
    stroke-width: 2
    stroke-dash: 5
    font-color: "#88C0D0"
    animated: true
  }
}

Available Style Properties

PropertyApplies ToDescription
fillShapesBackground color
strokeShapes, connectionsBorder / line color
stroke-widthShapes, connectionsBorder / line thickness
stroke-dashShapes, connectionsDash pattern (0 = solid)
font-colorShapes, connectionsText color
font-sizeShapes, connectionsText size
border-radiusShapesCorner rounding
shadowShapesDrop shadow
opacityShapesTransparency (0.0 - 1.0)
boldShapes, connectionsBold text
italicShapes, connectionsItalic text
underlineShapes, connectionsUnderlined text
animatedConnectionsAnimated dashes

Classes (Reusable Styles)

Define reusable style classes and apply them to multiple elements.

d2
classes: {
  primary: {
    style: {
      fill: "#5E81AC"
      font-color: "#ECEFF4"
      border-radius: 8
    }
  }
  database: {
    shape: cylinder
    style: {
      fill: "#A3BE8C"
      font-color: "#2E3440"
    }
  }
  external: {
    style: {
      fill: "#BF616A"
      font-color: "#ECEFF4"
      stroke-dash: 5
    }
  }
}

api: API Server {
  class: primary
}
db: PostgreSQL {
  class: database
}
stripe: Stripe API {
  class: external
}

api -> db
api -> stripe

Icons

D2 supports icons from URLs. Commonly used with icon sets hosted online.

d2
aws: AWS {
  icon: https://icons.terrastruct.com/aws%2F_Group%20Icons%2FAWS-Cloud-alt_light-bg.svg
}

postgres: PostgreSQL {
  icon: https://icons.terrastruct.com/dev%2Fpostgresql.svg
  shape: image
}

github: GitHub Actions {
  icon: https://icons.terrastruct.com/dev%2Fgithub.svg
}

Grid Layouts

Grid layouts arrange child elements in a grid pattern.

d2
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.

d2
# 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.

d2
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.

d2
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.

EngineDescriptionBest For
dagreDefault. Fast, hierarchical layout.Most diagrams. Free and open source.
ELKEclipse Layout Kernel. More advanced algorithms.Complex diagrams with many connections. Free and open source.
TALATerrastruct's proprietary engine. Best quality.Presentation-quality diagrams. Requires license.

Specifying Layout Engine

bash
# 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:

d2
direction: right

Direction

d2
direction: right  # left-to-right (default: down/top-to-bottom)

Available directions: up, down, left, right

CLI Commands

bash
# 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.

Complete Example

d2
direction: right

title: E-Commerce Architecture {
  near: top-center
  shape: text
  style.font-size: 24
  style.bold: true
}

classes: {
  service: {
    style: {
      fill: "#5E81AC"
      font-color: "#ECEFF4"
      border-radius: 8
    }
  }
  datastore: {
    shape: cylinder
    style: {
      fill: "#A3BE8C"
      font-color: "#2E3440"
    }
  }
  external: {
    style: {
      fill: "#BF616A"
      font-color: "#ECEFF4"
      stroke-dash: 5
    }
  }
  client: {
    style: {
      fill: "#88C0D0"
      font-color: "#2E3440"
      border-radius: 12
    }
  }
}

customer: Customer {
  shape: person
}

frontend: Frontend {
  class: client
  web: Web App (Next.js)
  mobile: Mobile App (React Native)
}

backend: Backend Services {
  api: API Gateway {
    class: service
  }
  catalog: Catalog Service {
    class: service
  }
  orders: Order Service {
    class: service
  }
  auth: Auth Service {
    class: service
  }
}

data: Data Layer {
  catalog_db: Catalog DB {
    class: datastore
  }
  order_db: Order DB {
    class: datastore
  }
  cache: Redis Cache {
    class: datastore
  }
  queue: Message Queue {
    shape: queue
    style.fill: "#D08770"
  }
}

external: External Services {
  stripe: Stripe {
    class: external
  }
  sendgrid: SendGrid {
    class: external
  }
}

customer -> frontend.web: HTTPS
customer -> frontend.mobile: HTTPS

frontend.web -> backend.api: REST/GraphQL
frontend.mobile -> backend.api: REST/GraphQL

backend.api -> backend.auth: Verify token
backend.api -> backend.catalog: Product queries
backend.api -> backend.orders: Order management

backend.catalog -> data.catalog_db
backend.catalog -> data.cache
backend.orders -> data.order_db
backend.orders -> data.queue: Publish events

data.queue -> external.sendgrid: Order confirmation emails
backend.orders -> external.stripe: Process payment

Best Practices

  • 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.