pma-d2
D2 Diagram Author
Generate idiomatic .d2 source files — diagrams encoded as declarative text, rendered by the official d2 CLI to SVG / PNG / PDF / GIF. The output is human-readable, diffable, and embeds anywhere D2 embeds (GitHub, Notion, VS Code, docs sites, Oxide's play.d2lang.com).
Keep this entry file small. Load only the reference packs that match the current diagram.
Always-On Rules
- Output is
.d2text, nothing else. The skill never invokes a renderer; the user runsd2 input.d2 out.svgor opens play.d2lang.com. Quality must be enforceable by reading the source. - Idiomatic D2 over clever D2. Prefer declarative node names (
api -> db) over IDs + labels when the name reads naturally. Reach forlabel:only when the natural name would be awkward or duplicated. - Shape type matches concept. A database is
shape: cylinder, a queue isshape: queue, an actor isshape: person. Never default everything torectangle. Full catalog inreferences/shapes.md. - Direction declared up front. Set
direction: down | right | up | lefton the root (and per container if needed). Layout direction is a communication choice, not an incidental default. - Semantic edge style, not ornamental.
stroke-dashfor async / weak dependency;animated: truefor streams;strokecolor to encode criticality / failure paths. Catalog inreferences/connections.md. - Group by container, not by proximity. If nodes belong to one domain (a subsystem, a cloud, a bounded context), nest them in a container map. Containers are D2's native grouping — use them instead of manual placement.
- One concept per diagram. If a diagram answers two questions, split into two
layers:or two files. Don't compress. - Classes for repetition. ≥ 2 nodes share styling → define a class in
classes: {}and apply with.class: nameor a glob. - No invented shapes. All
shape:values must come fromreferences/shapes.md. D2 silently falls back to rectangle on typos, which is the worst failure mode: it looks right but isn't. - Commit-ready source. File ends with a newline, uses 2-space indentation, no trailing whitespace, comments explain intent not mechanics. D2 is git-friendly — keep it that way.
Core Workflow
Step 1: Choose Diagram Family
| Family | D2 primitive | Use when |
|---|---|---|
| Architecture / flow | default (nodes + connections) | Systems, pipelines, dependency graphs |
| Sequence | shape: sequence_diagram |
Protocol exchanges, API call flows, timing |
| ERD / schema | shape: sql_table per table |
Data model, foreign keys |
| UML class | shape: class per class |
OO design, type relationships |
| Grid / matrix | grid-rows / grid-columns |
Tabular layouts, comparison matrices, k8s cluster views |
| Multi-board | layers: / scenarios: / steps: |
Before/after, drill-down, animation |
Details per family in references/special-diagrams.md and references/composition.md.
Step 2: Pick Layout Engine
- dagre (default, free, bundled): DAG-oriented, good for most architecture diagrams.
- elk (free, bundled since v0.7): cleaner for nested hierarchies and orthogonal routing. Worth trying for multi-container diagrams.
- tala (paid, separate binary): best-in-class for complex, dense diagrams. Note in the file header if required so the user knows what to install.
Pick once per file via vars.d2-config.layout-engine. Don't fight the engine with manual positions — D2 has no x,y.
Step 3: Draft Structure
- Sketch the top-level containers first: which systems / domains exist.
- Add nodes inside each container with the correct
shape:. - Add connections — direction first, labels after topology is right.
- Apply
classes:to collapse repetition. - Add
vars.d2-configblock (theme, layout engine) at the top.
Step 4: Style Pass
- Walk every connection — is its style (solid / dashed / animated / color) semantically distinct from its neighbors'?
- Walk every node — does its
shape:and class carry information? - Remove ornamentation that doesn't encode meaning (decorative colors, gratuitous shadows).
Step 5: Validate & Hand Off
Run the pre-flight in references/validation.md. Tell the user:
- The output path (default
docs/architecture/<name>.d2). - The render command:
d2 <name>.d2 <name>.svg(or whatever target they need). - The chosen layout engine and whether it requires a separate install.
- Any icons referenced by URL (so they can mirror internally if needed).
Section-by-Section for Large Diagrams
- Write the
vars+directionheader and one container. - Append one container per edit; prefix child IDs by container if they'd otherwise collide.
- Cross-container edges use dotted paths (
aws.api -> gcp.auth); verify the path exists before emitting the edge. - When a diagram grows past ~60 nodes, split into
layers:or separate.d2files composed via@fileimports (references/composition.md).
Output
- File:
docs/architecture/<name>.d2by default, or a path the user specifies. - Render (user runs):
d2 name.d2→name.svg(default)d2 name.d2 name.png/name.pdf/name.gifd2 --watch name.d2→ live preview on localhostd2 --theme <id> --dark-theme <id> name.d2→ theme pairing
- Web preview: paste into https://play.d2lang.com/ for instant rendering without installing D2.
- Embedding: see
references/integration.mdfor MDX, GitHub READMEs (checked-in SVG), docs sites (live render at build time), and CI pipelines.
Reference Packs
references/syntax.mdCore grammar: identifiers, labels, maps, comments, escaping, the shorthand rules D2 is full of.references/shapes.mdEvery built-in shape with picture description, data semantics, and "use when" guidance.references/connections.mdEdge operators (->,<-,<->,--), chaining, arrowheads, labels, semantic styling patterns.references/containers.mdNesting,_parent refs, dotted paths, the difference between a container and a shape, when to flatten vs nest.references/classes.mdclasses:block, applying via.class:, multi-class arrays, glob-based mass application.references/styles.mdComplete style key catalog (fill, stroke, stroke-dash, shadow, 3d, multiple, animated, fill-pattern, border-radius, font-size, bold/italic/underline, opacity).references/layouts.mdDirection, grid layouts, dagre vs elk vs tala tradeoffs,near:positioning for titles and legends.references/special-diagrams.mdSequence diagrams (actors, spans, notes, groups),sql_tableERDs,classUML, markdown / code / LaTeX blocks.references/composition.mdlayers:(isolated boards),scenarios:(inherit + override),steps:(animation),@fileimports,...@filespread.references/vars.mdvars:block,${var}substitution,d2-config(theme-id, dark-theme-id, sketch, pad, center, layout-engine), nested vars for design tokens.references/templates.mdCopy-paste starter files: 3-tier web, microservices, data pipeline, CI/CD, sequence (OAuth), ERD, k8s cluster (grid).references/design.mdConcept→pattern mapping, isomorphism test, when D2 beats ReactFlow / Mermaid / Excalidraw, when it loses.references/validation.mdPre-flight algorithm and checklists; common D2 mistakes (silent shape fallback, missing container path, label vs comment collisions).references/render.mdCLI flags, watch mode, playground, icon catalogs (terrastruct icons, svgrepo), theme gallery.references/integration.mdMDX / Docusaurus / Nextra embedding, GitHub README via checked-in SVG, docs-site build pipelines, pre-commit render.
Quick Routing
- New to D2 syntax: load
syntax.md+shapes.md+connections.md. - Architecture / system diagram:
shapes.md+containers.md+layouts.md+templates.md. - Sequence / SQL / UML:
special-diagrams.md+templates.md. - Styling pass:
classes.md+styles.md. - Multi-board story (before/after, drill-down, animation):
composition.md. - Theming / config:
vars.md+render.md. - Before delivering:
validation.md. - Telling the user how to render or embed:
render.md+integration.md.
If the project also uses /pma for workflow control, load /pma first, then /pma-d2 only when a diagram is required. If the project needs interactive, in-browser diagrams with custom React node components, use /pma-draw instead — D2 renders to static images.
More from zzci/skills
pma
Project development lifecycle management with a strict three-phase workflow (investigate -> proposal -> implement), file-based plan tracking in docs/plan/, task tracking in docs/task/, and claim-before-work multi-agent coordination. Use when handling feature development, bug fixes, refactors, planning, progress tracking, or multi-agent execution in an existing codebase. English-first for repository docs and remote-visible metadata; use Chinese docs only when the user explicitly requests a specific document in Chinese.
116pma-web
Frontend implementation guide for PMA-managed React 19 + TypeScript + Vite 8 SPA projects. Defaults to a single-app layout (the right choice for a Rust/Go service that ships a UI); promotes to a Bun monorepo only when multiple apps or shared packages exist. UI is hard-locked to shadcn/ui (base-nova) + `@base-ui/react` — Radix and other UI ecosystems (MUI / Mantine / Chakra / Ant Design / Headless UI / Ariakit / NextUI / …) are forbidden. Covers required quality gates, file-based type-safe routing with TanStack Router, state conventions (TanStack Query + Zustand), Tailwind CSS v4 patterns, Vitest 4 testing, dual-channel theming, i18n, nsl-based dev integration with backend services, and delivery rules for frontend applications.
108pma-rust
Rust implementation guide for PMA-managed multi-crate workspace projects. Covers workspace config, pinned stable toolchains, strict linting with clippy and cargo-cranky, async data access (Diesel-async or SQLx), Axum/Tokio service patterns, layered config with figment + clap, rustls-only TLS, OpenTelemetry observability, and CI quality gates.
94bkd
Operate a BKD kanban board over its REST API. Use when the user wants to manage BKD projects, issue execution workflows, cron jobs, or execution capacity through a reachable BKD server.
93pma-cr
Stack-aware review for local diffs, pull requests, and repository-wide audits. Routes review across shared policy plus language packs for TypeScript frontend, TypeScript backend/Bun, Go, Rust, and Python. Use after implementation, before merge, or when auditing an existing codebase.
91pma-go
Go implementation guide for PMA-managed service and CLI projects. Covers project layout (cmd/internal), strict linting with golangci-lint v2, database access (sqlc + pgx or GORM), HTTP patterns (stdlib + Chi or Gin), layered config with koanf, structured logging with slog, OpenTelemetry observability, and CI quality gates.
91