Generate visual flow diagrams, architecture diagrams, and system maps as SVG/PNG. Use when the user asks for flowcharts, user flow diagrams, architecture dia...
---
name: diagrams
description: Generate visual flow diagrams, architecture diagrams, and system maps as SVG/PNG. Use when the user asks for flowcharts, user flow diagrams, architecture diagrams, system diagrams, interaction maps, or any visual diagram. Supports ELK JSON layout engine with automatic rendering to SVG.
---
# Diagrams
Generate diagrams from structured JSON β SVG (and optionally PNG).
## Quick Start
1. **Install elkjs** in the target directory (if not already present):
```bash
cd <project>/docs/diagrams && npm init -y && npm install elkjs
# Set "type": "module" in package.json
```
2. **Write ELK JSON** files describing the diagram (see schema below)
3. **Render:**
```bash
# Single file
node <skill-dir>/scripts/render-elk.mjs diagram.json output.svg
# Batch: all .json files in a folder β svg/ subfolder
node <skill-dir>/scripts/render-elk.mjs --dir <folder>
# Batch + PNG (macOS only, uses sips)
node <skill-dir>/scripts/render-elk.mjs --dir <folder> --png
```
4. **Embed in markdown:**
```markdown

```
## ELK JSON Schema
```json
{
"id": "root",
"title": "Diagram Title (rendered as heading)",
"layoutOptions": {
"elk.algorithm": "layered",
"elk.direction": "DOWN",
"elk.spacing.nodeNode": "30",
"elk.layered.spacing.nodeNodeBetweenLayers": "40",
"elk.padding": "[top=40,left=20,bottom=20,right=20]"
},
"children": [
{
"id": "node1",
"width": 220,
"height": 45,
"labels": [{"text": "Node label for ELK layout"}],
"label": "π¦ Display label (rendered in SVG)",
"color": "core",
"subtitle": "Optional second line"
}
],
"edges": [
{
"id": "e1",
"sources": ["node1"],
"targets": ["node2"],
"labels": [{"text": "Yes", "width": 25, "height": 14}],
"edgeColor": "#10B981",
"dashed": true
}
]
}
```
### Node Properties
| Property | Type | Description |
|----------|------|-------------|
| `id` | string | Required. Unique identifier |
| `width` | number | Node width in px (default 120) |
| `height` | number | Node height in px (default 40) |
| `labels` | array | `[{text}]` β used by ELK for layout calculation |
| `label` | string | Display text rendered in SVG (supports emoji). Falls back to `id` |
| `color` | string | Color key from palette (see below) |
| `subtitle` | string | Smaller text below the label |
| `fontSize` | number | Label font size (default 13) |
| `children` | array | Nested nodes β makes this a container |
| `containerColor` | string | Color key for container background |
### Edge Properties
| Property | Type | Description |
|----------|------|-------------|
| `id` | string | Required. Unique identifier |
| `sources` | string[] | Source node id(s) |
| `targets` | string[] | Target node id(s) |
| `labels` | array | `[{text, width, height}]` β edge labels |
| `edgeColor` | string | Hex color (default `#64748B`) |
| `dashed` | boolean | Dashed line style |
| `strokeWidth` | number | Line thickness (default 1.5) |
### Color Palette
8 semantic colors. Every node maps to one. A legend auto-renders at the bottom of each SVG.
| Key | Color | Meaning | Use For |
|-----|-------|---------|---------|
| `action` | π΅ Blue | **System action** | Steps the app performs β API calls, DB writes, cron triggers |
| `external` | π’ Teal | **External service** | Third-party APIs β Google, Twilio, Stripe, Resend |
| `decision` | π©· Pink | **Decision point** | Yes/no branches, if/else, conditional checks |
| `user` | π Orange | **User action** | Things the user does β clicks, inputs, reviews |
| `success` | π’ Green | **Positive outcome** | Done, confirmed, created, visible |
| `negative` | π΄ Red | **Negative outcome** | Canceled, error, failed, not built |
| `neutral` | β« Gray | **Neutral / info** | Starting points, labels, inactive, informational |
| `data` | π‘ Amber | **Data / artifact** | Records, drafts, outputs, intermediate data |
Set `"legend": false` on the root graph to hide the auto-legend.
### Layout Options
Common `layoutOptions` values:
- `elk.direction`: `DOWN` (default), `RIGHT`, `LEFT`, `UP`
- `elk.algorithm`: `layered` (default, best for flowcharts), `force`, `stress`
- `elk.spacing.nodeNode`: Space between sibling nodes (px)
- `elk.layered.spacing.nodeNodeBetweenLayers`: Space between layers (px)
- `elk.padding`: `[top=N,left=N,bottom=N,right=N]`
## Design Tips
- **Sizing:** 200-280px wide for most nodes. 45px tall for single-line, 55px for two-line labels.
- **Decision nodes:** Use `context` (pink) color for yes/no branching.
- **Edge labels:** Keep short (Yes/No/Error). Set `width`/`height` for proper positioning.
- **Containers:** Add `children` array to a node. Use `containerColor: "step"` for a light blue group.
- **Manual trips vs automated:** Use `dashed: true` on edges for alternative/optional paths.
- **Title:** Set `title` on the root graph for a rendered heading above the diagram.
- **Emoji in labels:** Supported and encouraged for visual scanning.
## Gotchas
- **Container layout:** ELK's layered algorithm with nested containers in `RIGHT` direction can produce overlapping layouts. Prefer `DOWN` for containers, or flatten to a non-container layout if horizontal.
- **`labels` vs `label`:** `labels` (array) is what ELK uses for layout spacing. `label` (string) is what gets rendered in the SVG. Always set both β `labels[0].text` should approximate the display label length for correct sizing.
- **`package.json` must have `"type": "module"`** for the ESM import to work.
- **elkjs must be installed locally** in the directory where you run the script. It's not global.
don't have the plugin yet? install it then click "run inline in claude" again.