Diagrams as Code
Guide agents to maintain architecture, sequence, and deployment topology with declarative syntax so diagrams travel through PRs and history like source.
In the SKILL, pick a primary DSL (e.g. Mermaid flow/sequence, C4-PlantUML, DOT) and storage path (e.g. docs/diagrams/), and note whether node naming, styling, and legends match existing docs.
Large diagrams can split into subgraphs or layers (context, container, component) so diffs stay readable; for sensitive environments, specify whether hostnames or internal ranges must be omitted.
If the pipeline renders PNG/SVG, document triggers and caching so agents do not commit generated assets that drift from text sources.
- Syntax validation: run mmdc, plantuml, etc. locally or in CI with readable line numbers on failure.
- Cross-link READMEs/ADRs: source paths and embed strategy (links, includes) should be explicit.
- Pin renderer versions in the SKILL or package.json to avoid “works locally, fails in CI”.
Mermaid: 5 Diagram Type Examples
Lightweight diagrams for Markdown/GitHub/GitLab previews. The SKILL should require English node IDs inside ```mermaid fences and forbid remote images.
1. flowchart
```mermaid
flowchart TD
A([User request]) --> B{Auth?}
B -- pass --> C[Business logic]
B -- fail --> D([Return 401])
C --> E[(Database)]
E --> F([Return response])
```
2. sequenceDiagram
```mermaid
sequenceDiagram
actor User
participant API
participant Auth
participant DB
User->>API: POST /login {email, password}
API->>Auth: verifyCredentials()
Auth->>DB: SELECT user WHERE email=?
DB-->>Auth: User row
Auth-->>API: JWT token
API-->>User: 200 {token}
```
3. classDiagram
```mermaid
classDiagram
class Order {
+String id
+OrderStatus status
+List~Item~ items
+calculateTotal() float
}
class Item {
+String sku
+int quantity
+float price
}
class OrderStatus {
<<enumeration>>
PENDING
PAID
SHIPPED
}
Order "1" --> "*" Item : contains
Order --> OrderStatus : has
```
4. gitGraph (Git branch diagram)
```mermaid
gitGraph
commit id: "init"
branch feature/login
checkout feature/login
commit id: "add login form"
commit id: "add auth service"
checkout main
merge feature/login id: "merge login"
branch hotfix/token
checkout hotfix/token
commit id: "fix token expiry"
checkout main
merge hotfix/token id: "hotfix merged"
```
5. erDiagram (Entity-Relationship diagram)
```mermaid
erDiagram
USER {
uuid id PK
string email UK
string name
timestamp created_at
}
ORDER {
uuid id PK
uuid user_id FK
decimal total
string status
}
ORDER_ITEM {
uuid id PK
uuid order_id FK
string sku
int quantity
decimal price
}
USER ||--o{ ORDER : places
ORDER ||--|{ ORDER_ITEM : contains
```
Below is a live in-page render example (only this page loads Mermaid; other site pages do not depend on it).
PlantUML vs Mermaid Selection Guide
Strong fit for C4, rich sequence, and deployment diagrams; usually rendered via Jar, Docker, or Kroki. The SKILL should state whether !include and remote theme file paths are allowed.
Prefer Mermaid Prefer PlantUML ───────────────── ──────────────────────── GitHub/GitLab native rendering C4 architecture (C4-PlantUML library) Embedded in Markdown (README/ADR) Complex deployment / network topology Simple flowchart/sequence/class Need !include for reusable fragments Frontend team maintenance Need fine-grained style and theme control Fast iteration, diff-first Architecture review, precision-first No server dependency Existing Kroki / PlantUML service
@startuml C4-Container
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
Person(user, "User", "Using a web browser")
System_Boundary(sys, "E-commerce System") {
Container(web, "Web App", "React", "Provides shopping interface")
Container(api, "API Service", "Node.js/Express", "Handles business logic")
ContainerDb(db, "Database", "PostgreSQL", "Stores orders and user data")
}
Rel(user, web, "Uses", "HTTPS")
Rel(web, api, "Calls", "REST/JSON")
Rel(api, db, "Reads/Writes", "SQL")
@enduml
Mermaid CI rendering configuration (GitHub Actions):
# .github/workflows/diagrams.yml
name: Render Diagrams
on:
pull_request:
paths: ['docs/diagrams/**/*.mmd', 'docs/**/*.md']
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npm i -g @mermaid-js/mermaid-cli@10
- name: Validate all .mmd files
run: |
find docs/diagrams -name '*.mmd' | while read f; do
mmdc --input "$f" --output /tmp/out.svg || exit 1
done
PR and render workflow
Typical path from edit to merge; agent steps can map to “edit source → local validate → commit → CI”.
[ Edit .mmd / PlantUML / DOT ]
│
▼
[ Local: mmdc / plantuml / dot ]
│
┌────────┴────────┐
▼ ▼
[ Syntax OK ] [ Error: line number ]
│ │
│ └──► [ Fix source, rerun ]
▼
[ Readable git diff ]
│
▼
[ Open PR: embed or link docs/diagrams/ ]
│
▼
[ CI: pinned renderer / optional SVG output ]
│
├────► [ Pass → merge ]
└────► [ Fail → fix text, avoid stale binaries ]
On-page tool: fenced DSL scan
The script below runs only here: paste README or design drafts to list closed fences tagged mermaid, plantuml/puml, dot/graphviz with line ranges—useful to verify SKILL and CI coverage.
SKILL outline
Copy as a skeleton, then substitute real paths and render commands from your repo.
---
name: diagram-as-code
description: Maintain versioned architecture and flow diagrams with Mermaid/PlantUML and related DSLs
---
# Rules
- Store diagram source files in docs/diagrams/, organized by type (flow/sequence/c4)
- Prefer Mermaid for README/ADR embedding; use PlantUML for C4/complex deployment diagrams
- Node IDs must be in English; no external image links; do not commit generated PNG/SVG binaries
- PRs must include diagram source file changes; CI validates syntax (mmdc --input or plantuml -syntax)
- Pin versions: document mermaid-cli version in package.json devDependencies
# Steps
1. Confirm DSL choice (Mermaid vs PlantUML) and directory convention from the SKILL
2. Choose diagram type by use case:
- Flow logic → flowchart TD/LR
- API interaction → sequenceDiagram
- Data model → erDiagram / classDiagram
- Git branches → gitGraph
- Architecture layers → C4-PlantUML (Context/Container/Component)
3. For large diagrams, split into subgraphs or layered files to keep single-file diffs readable
4. Validate locally: mmdc --input diagram.mmd --output /tmp/out.svg
5. CI setup: add a validate-diagrams job to PR checks
6. Embed in README with a relative path: 