Claude
Skills
Sign in
Back

d2-diagrams

Included with Lifetime
$97 forever

This skill should be used when the user asks to "create a diagram", "draw an architecture diagram", "visualize a flow", "make a system diagram", "generate a D2 diagram", or mentions D2, architecture diagrams, flow diagrams, sequence diagrams, or system visualization.

General

What this skill does


# D2 Diagram Generation

Generate professional diagrams using [D2](https://d2lang.com/), render them to PNG, visually evaluate the output, and iterate until the result is clean and readable.

## Prerequisites

Verify D2 is installed before starting:

```bash
which d2 || brew install d2
```

## C4 Model Framework

Use the [C4 model](https://c4model.com/) to decide the right level of abstraction before drawing anything. C4 defines four zoom levels — pick the one that matches what the diagram needs to communicate.

**Reference:** D2 has first-class C4 support since v0.7. See the [official D2 C4 guide](https://d2lang.com/blog/c4/) for examples including the C4 theme, `c4-person` shape, markdown labels, `d2-legend`, and the `suspend` keyword for multi-view models.

### Level 1 — System Context

**When**: Showing how the system fits into the wider world. For stakeholders, onboarding, high-level architecture.

- The system under discussion is one box in the center
- Surround it with the **people** (users, roles) and **external systems** it interacts with
- No internal detail — just relationships and protocols
- Typically 3-8 nodes

```
[Person] → [Your System] → [External System]
```

D2: Use `shape: person` for actors, single node for the system, ovals for external systems.

### Level 2 — Container

**When**: Showing the major technical building blocks inside a system. For developers, debugging, understanding how services connect.

- The system boundary is a container (dashed border)
- Inside: services, databases, message queues, frontends — each is a **container**
- Show inter-container communication (HTTP, gRPC, Pub/Sub, SQL)
- External systems and people sit outside the boundary
- Typically 5-15 nodes

D2: Use a container with `boundary` class for the system boundary. Use technology classes (`go`/`java`/`ts`) for services, `db` class for databases, `queue` class for message brokers.

### Level 3 — Component

**When**: Zooming into a single container to show its internal components. For deep debugging, code review, design discussions.

- The container boundary is the outer frame
- Inside: major modules, packages, classes, or handler groups
- Show dependencies between components
- Typically 5-12 nodes within one container

### Level 4 — Code

**Rarely needed**. Class diagrams, sequence diagrams. Usually auto-generated from code rather than hand-drawn.

### Choosing the Right Level

| Situation | Level | Example |
|-----------|-------|---------|
| "How does the platform work?" | L1 Context | User → Platform → Payment Provider |
| "How do our services connect?" | L2 Container | API Gateway → Order Service → DB |
| "How does the order service handle a request?" | L3 Component | Validator → Processor → Notifier |
| "What are the classes in the processor?" | L4 Code | Usually skip — read the code instead |

**Default to Level 2 (Container)** unless the user specifies otherwise. It's the most useful level for debugging and onboarding.

## Workflow

### 1. Plan the Diagram

Before writing D2, decide:

- **C4 Level**: Which zoom level? (default: L2 Container)
- **Direction**: `down` for hierarchies/pipelines, `right` for sequential flows
- **Scope**: One story per diagram. If the system is complex, split into focused diagrams rather than one mega-diagram
- **Node ordering**: Arrange nodes so arrows flow in one direction. Minimize arrows going backwards or sideways — these cause crossings

**Rule of thumb**: If a diagram has more than ~10 nodes or arrows that must cross, split it.

### 1b. Verify Names from Code

Before putting a service or component on a diagram, verify its actual name from the codebase or deployment configs. Don't guess or use colloquial names — check K8s manifests, Terraform modules, or service entrypoints. Wrong names on architecture diagrams erode trust in the documentation.

**No codebase?** For conceptual/design diagrams, skip this step. See [references/d2-advanced.md](references/d2-advanced.md) § "Conceptual Diagrams" for naming conventions.

### 2. Write the D2 Source

Place `.d2` files where they'll be maintained alongside the project:

```bash
# In a project — keep diagrams with docs
mkdir -p docs/diagrams
# Write to docs/diagrams/<name>.d2, renders to docs/diagrams/<name>.svg

# Standalone / exploratory — use a scratch directory
mkdir -p /tmp/d2-work
```

**Convention**: Name files after what they show, not the system: `payment-flow.d2`, `auth-sequence.d2`, `system-context.d2`. Keep the `.d2` source committed alongside the rendered output so anyone can re-render.

Follow the style guide in [references/d2-style.md](references/d2-style.md).

### 3. Render

```bash
# SVG — preferred for docs, wikis, web (scalable, searchable text, smaller files)
d2 --theme 0 --layout elk --pad 60 <input>.d2 <output>.svg

# PNG — for presentations, chat, or when SVG isn't supported
d2 --theme 0 --layout elk --pad 60 <input>.d2 <output>.png
# Add --scale 2 for higher-DPI output (retina/print)
```

- `--theme 0` — clean light theme (best for docs/presentations). For standard C4 look, use `--theme 200` (C4 theme)
- `--layout elk` — Eclipse Layout Kernel, handles complex graphs better than default dagre
- `--pad 60` — breathing room around edges
- **SVG vs PNG**: Default to SVG. Use PNG when the consumer doesn't support SVG (Slack, most chat tools) or when visual evaluation is needed (the judge loop requires PNG since the Read tool can read images)

### 4. Evaluate (Judge Loop)

Read the rendered PNG using the Read tool and evaluate against these criteria. **Score each 1-10, iterate until ALL are >= 8:**

| Criteria | What to check |
|----------|---------------|
| **C4 compliance** | Does the diagram follow C4 conventions for the chosen level? See the checklist below. |
| **Flow** | Do arrows follow one dominant direction (top→bottom or left→right)? Are there crossing arrows? Arrows going backwards? |
| **Readability** | Is all text legible? Are labels truncated? Is the diagram too wide/flat or too tall/narrow? |
| **Grouping** | Are related nodes visually close? Is there clear visual hierarchy? |
| **Simplicity** | Is every node and arrow necessary? Could anything be removed or split into a separate diagram? |

#### C4 Compliance Checklist (verify before rendering)

Run through this before every render. If any item is "no", fix the D2 source first.

- [ ] **Classes from the style guide only.** Every class used comes from [references/d2-style.md](references/d2-style.md). Do not invent custom classes.
- [ ] **Technology annotations on every node.** C4 format: `"name\n[Container: Tech]"` (e.g., `"order-service\n[Container: Go]"`) or shorthand `"name\n[Tech — role]"` (e.g., `"scheduler\n[Go — K8s CronJob]"`). No node should be just a name with no context.
- [ ] **Protocol labels on every edge.** Format: `"description\n[Protocol]"` (e.g., `"creates order\n[SQL]"`). Use `[SQL]`, `[gRPC]`, `[Pub/Sub]`, `[HTTPS]`, `[REST]`.
- [ ] **System boundary present** (L2+). A `boundary` class container wrapping internal components. External actors sit outside it.
- [ ] **External actors outside the boundary.** Users, triggers, external systems are not inside the system boundary.
- [ ] **No invented concepts.** The diagram shows architecture (what connects to what), not behavior or failure states. Failure modes, error paths, and "what happens when X breaks" belong in text, not in the diagram.

**Common fixes by symptom:**

| Symptom | Fix |
|---------|-----|
| Too wide/flat, text tiny | Switch `direction: right` → `direction: down` |
| Crossing arrows | Reorder node declarations. D2/ELK places nodes in declaration order |
| Spaghetti connections | Split into multiple diagrams. Remove secondary connections |
| Nodes scattered randomly | Use containers to group related nodes |
| Labels truncated | Shorten label text, use `\n` for line breaks |
| Too many edge labels | Remove obvious labels, keep only the non-obvious ones |

### 5. Iterate

If any criterion scores below 8:

1. 

Related in General