Excalidraw Diagrams
Create hand-drawn style diagrams, flowcharts, architecture diagrams, and mind maps using the Excalidraw format. Diagrams are rendered interactively in the Canvas panel.
When to Use This Skill
Use create_excalidraw_diagram when the user wants to visualize structure, flow, or relationships — not raw numbers.
| Use this skill for... |
Use visualization skill for... |
| System architecture diagram |
Sales figures by quarter |
| Flowchart or decision tree |
Survey response percentages |
| Sequence / interaction diagram |
Stock price over time |
| Mind map or concept map |
Market share breakdown |
| Shapes, boxes, arrows, labels |
Any x/y or segment/value data |
Diagram Type
Choose based on user intent. For Swimlane, Class, Sequence, ER, and DFD diagrams, read diagram-patterns.md before generating.
| Intent |
Type |
Pattern |
| Process steps, workflow, decisions |
Flowchart |
Rectangles + diamonds + arrows (see Example) |
| System components, dependencies |
Architecture |
Zone rectangles + boxes + arrows |
| Concept hierarchy, brainstorming |
Mind Map |
Center node + radial branch arrows |
| Entity connections, associations |
Relationship |
Boxes + labeled arrows |
| Cross-functional workflow, actor responsibilities |
Swimlane |
diagram-patterns.md |
| OOP class structure, inheritance |
Class Diagram |
diagram-patterns.md |
| Object interactions over time |
Sequence Diagram |
diagram-patterns.md |
| Database entities and relationships |
ER Diagram |
diagram-patterns.md |
| Data transformation, data movement |
DFD |
diagram-patterns.md |
Available Tools
- create_excalidraw_diagram(elements, title, background_color): Generate a diagram from Excalidraw element JSON
Color Palette
Use these colors consistently across all diagrams.
Primary Colors (strokes, arrows, text)
| Name |
Hex |
Use |
| Blue |
#4a9eed |
Primary actions, links |
| Amber |
#f59e0b |
Warnings, highlights |
| Green |
#22c55e |
Success, positive |
| Red |
#ef4444 |
Errors, negative |
| Purple |
#8b5cf6 |
Accents, special items |
| Cyan |
#06b6d4 |
Info, secondary |
Fill Colors (shape backgrounds)
| Color |
Hex |
Good For |
| Light Blue |
#a5d8ff |
Input, sources, primary nodes |
| Light Green |
#b2f2bb |
Success, output, completed |
| Light Orange |
#ffd8a8 |
Warning, pending, external |
| Light Purple |
#d0bfff |
Processing, middleware |
| Light Red |
#ffc9c9 |
Error, critical |
| Light Yellow |
#fff3bf |
Notes, decisions |
| Light Teal |
#c3fae8 |
Storage, data |
Background Zone Colors (use with opacity: 35 for layer grouping)
| Color |
Hex |
Good For |
| Blue zone |
#dbe4ff |
UI / frontend layer |
| Purple zone |
#e5dbff |
Logic / agent layer |
| Green zone |
#d3f9d8 |
Data / tool layer |
Element Format
Required Fields (all elements)
type, id (unique string), x, y, width, height
Defaults (skip if using these values)
strokeColor="#1e1e1e", backgroundColor="transparent", fillStyle="solid", strokeWidth=2, roughness=1, opacity=100
Shape Types
Rectangle
{ "type": "rectangle", "id": "r1", "x": 100, "y": 100, "width": 200, "height": 80,
"roundness": { "type": 3 }, "backgroundColor": "#a5d8ff", "fillStyle": "solid" }
roundness: { type: 3 } for rounded corners
Ellipse
{ "type": "ellipse", "id": "e1", "x": 100, "y": 100, "width": 150, "height": 150 }
Diamond
{ "type": "diamond", "id": "d1", "x": 100, "y": 100, "width": 150, "height": 150 }
Label on shape (PREFERRED — no separate text element needed)
{ "type": "rectangle", "id": "r1", "x": 100, "y": 100, "width": 200, "height": 80,
"label": { "text": "My Label", "fontSize": 20 } }
- Works on rectangle, ellipse, diamond
- Text auto-centers; container auto-resizes to fit
- Also works on arrows:
"label": { "text": "connects" }
Standalone Text (titles, annotations only)
{ "type": "text", "id": "t1", "x": 150, "y": 50, "text": "Title", "fontSize": 24 }
x is the LEFT edge. To center at position cx: set x = cx - text.length × fontSize × 0.25
Arrow
{ "type": "arrow", "id": "a1", "x": 300, "y": 150, "width": 150, "height": 0,
"points": [[0,0],[150,0]], "endArrowhead": "arrow",
"startBinding": { "elementId": "r1", "fixedPoint": [1, 0.5] },
"endBinding": { "elementId": "r2", "fixedPoint": [0, 0.5] } }
points: [dx, dy] offsets from element x, y
endArrowhead: null | "arrow" | "bar" | "dot" | "triangle"
strokeStyle: "solid" | "dashed" | "dotted"
fixedPoint for bindings: top [0.5,0], bottom [0.5,1], left [0,0.5], right [1,0.5]
Pseudo-Elements (not drawn — control behavior)
cameraUpdate — sets the viewport
{ "type": "cameraUpdate", "width": 800, "height": 600, "x": 0, "y": 0 }
x, y: top-left corner of visible area (scene coordinates)
- Must be 4:3 ratio: 400×300, 600×450, 800×600, 1200×900, 1600×1200
- ALWAYS place a
cameraUpdate as the first element to frame the diagram
- No
id needed
delete — removes elements by ID
{ "type": "delete", "ids": "r1,a1,t2" }
- Comma-separated element IDs to remove
- Use when updating an existing diagram to remove elements before adding replacements
- Never reuse a deleted ID — assign new IDs to replacements
Camera Sizing Guide
The diagram displays at ~700px width. Use these standard sizes:
| Size |
Width × Height |
Use When |
| S |
400 × 300 |
2–3 elements, close-up |
| M |
600 × 450 |
Small diagram section |
| L |
800 × 600 |
Standard (default) |
| XL |
1200 × 900 |
Large overview |
| XXL |
1600 × 1200 |
Very complex diagrams |
Font size rules:
- Body text / labels: minimum 16
- Titles / headings: minimum 20
- Annotations: minimum 14 (use sparingly)
- At XL/XXL camera: increase minimums by ~4px
Element sizing rules:
- Labeled rectangles/ellipses: minimum 120 × 60
- Leave 20–30px gaps between elements
Updating an Existing Diagram
When the user asks to modify a diagram, you will receive the current elements in context. Respond with the complete updated elements array:
- Keep the same
id for unchanged elements
- Modify fields on elements you want to change
- Omit elements you want to remove
- Add new elements with unique IDs not used before
Example: Flowchart
[
{ "type": "cameraUpdate", "width": 800, "height": 600, "x": 0, "y": 0 },
{ "type": "rectangle", "id": "el-1",
"x": 300, "y": 60, "width": 160, "height": 60,
"strokeColor": "#4a9eed", "backgroundColor": "#a5d8ff",
"fillStyle": "solid", "roundness": { "type": 3 },
"label": { "text": "Start", "fontSize": 18 } },
{ "type": "diamond", "id": "el-2",
"x": 280, "y": 170, "width": 200, "height": 90,
"strokeColor": "#f59e0b", "backgroundColor": "#fff3bf",
"fillStyle": "solid",
"label": { "text": "Decision?", "fontSize": 16 } },
{ "type": "arrow", "id": "el-3",
"x": 380, "y": 120, "width": 0, "height": 50,
"points": [[0,0],[0,50]], "endArrowhead": "arrow",
"startBinding": { "elementId": "el-1", "fixedPoint": [0.5, 1] },
"endBinding": { "elementId": "el-2", "fixedPoint": [0.5, 0] } },
{ "type": "rectangle", "id": "el-4",
"x": 300, "y": 320, "width": 160, "height": 60,
"strokeColor": "#22c55e", "backgroundColor": "#b2f2bb",
"fillStyle": "solid", "roundness": { "type": 3 },
"label": { "text": "End", "fontSize": 18 } },
{ "type": "arrow", "id": "el-5",
"x": 380, "y": 260, "width": 0, "height": 60,
"points": [[0,0],[0,60]], "endArrowhead": "arrow",
"startBinding": { "elementId": "el-2", "fixedPoint": [0.5, 1] },
"endBinding": { "elementId": "el-4", "fixedPoint": [0.5, 0] } }
]
Common Mistakes to Avoid
- Camera must use exact 4:3 ratios — non-4:3 viewports cause distortion
- Always start with cameraUpdate — without it the viewport is unpredictable
- No comments in element arrays —
elements must be valid JSON. Never add // or /* */ comments inside the array; they break JSON parsing
- Text contrast — never use light gray on white. Minimum text color on white:
#757575. For text on light fills use dark variants (#15803d not #22c55e)
- Arrow labels need space — long labels overflow short arrows; keep labels short or widen arrows
- No emoji — Excalidraw's font does not render emoji
- Element overlap — check that labels, boxes, and zone overlays don't stack on each other (minimum 20px gap)
- Camera padding — leave padding inside the camera frame; don't match camera size exactly to content size
UI Guidance (from tools-config)
Element Format:
- Required: type, x, y, id
- Shapes (rectangle/ellipse/diamond): add width, height
- Arrows/lines: add width, height, points [[0,0],[dx,dy]]
- Text: add text, fontSize
- Use label field on shapes for centered text
- Connect shapes with arrow elements using points routing
1---2name: excalidraw3description: Create hand-drawn style diagrams and flowcharts using Excalidraw4---56# Excalidraw Diagrams78Create hand-drawn style diagrams, flowcharts, architecture diagrams, and mind maps using the Excalidraw format. Diagrams are rendered interactively in the Canvas panel.910## When to Use This Skill1112Use `create_excalidraw_diagram` when the user wants to visualize **structure, flow, or relationships** — not raw numbers.1314| Use this skill for... | Use visualization skill for... |15|-----------------------|--------------------------------|16| System architecture diagram | Sales figures by quarter |17| Flowchart or decision tree | Survey response percentages |18| Sequence / interaction diagram | Stock price over time |19| Mind map or concept map | Market share breakdown |20| Shapes, boxes, arrows, labels | Any x/y or segment/value data |2122## Diagram Type2324Choose based on user intent. For Swimlane, Class, Sequence, ER, and DFD diagrams, read [diagram-patterns.md](diagram-patterns.md) before generating.2526| Intent | Type | Pattern |27|--------|------|---------|28| Process steps, workflow, decisions | Flowchart | Rectangles + diamonds + arrows (see Example) |29| System components, dependencies | Architecture | Zone rectangles + boxes + arrows |30| Concept hierarchy, brainstorming | Mind Map | Center node + radial branch arrows |31| Entity connections, associations | Relationship | Boxes + labeled arrows |32| Cross-functional workflow, actor responsibilities | Swimlane | [diagram-patterns.md](diagram-patterns.md) |33| OOP class structure, inheritance | Class Diagram | [diagram-patterns.md](diagram-patterns.md) |34| Object interactions over time | Sequence Diagram | [diagram-patterns.md](diagram-patterns.md) |35| Database entities and relationships | ER Diagram | [diagram-patterns.md](diagram-patterns.md) |36| Data transformation, data movement | DFD | [diagram-patterns.md](diagram-patterns.md) |3738## Available Tools3940- **create_excalidraw_diagram(elements, title, background_color)**: Generate a diagram from Excalidraw element JSON4142## Color Palette4344Use these colors consistently across all diagrams.4546### Primary Colors (strokes, arrows, text)47| Name | Hex | Use |48|------|-----|-----|49| Blue | `#4a9eed` | Primary actions, links |50| Amber | `#f59e0b` | Warnings, highlights |51| Green | `#22c55e` | Success, positive |52| Red | `#ef4444` | Errors, negative |53| Purple | `#8b5cf6` | Accents, special items |54| Cyan | `#06b6d4` | Info, secondary |5556### Fill Colors (shape backgrounds)57| Color | Hex | Good For |58|-------|-----|----------|59| Light Blue | `#a5d8ff` | Input, sources, primary nodes |60| Light Green | `#b2f2bb` | Success, output, completed |61| Light Orange | `#ffd8a8` | Warning, pending, external |62| Light Purple | `#d0bfff` | Processing, middleware |63| Light Red | `#ffc9c9` | Error, critical |64| Light Yellow | `#fff3bf` | Notes, decisions |65| Light Teal | `#c3fae8` | Storage, data |6667### Background Zone Colors (use with `opacity: 35` for layer grouping)68| Color | Hex | Good For |69|-------|-----|----------|70| Blue zone | `#dbe4ff` | UI / frontend layer |71| Purple zone | `#e5dbff` | Logic / agent layer |72| Green zone | `#d3f9d8` | Data / tool layer |7374## Element Format7576### Required Fields (all elements)77`type`, `id` (unique string), `x`, `y`, `width`, `height`7879### Defaults (skip if using these values)80`strokeColor="#1e1e1e"`, `backgroundColor="transparent"`, `fillStyle="solid"`, `strokeWidth=2`, `roughness=1`, `opacity=100`8182### Shape Types8384**Rectangle**85```json86{ "type": "rectangle", "id": "r1", "x": 100, "y": 100, "width": 200, "height": 80,87 "roundness": { "type": 3 }, "backgroundColor": "#a5d8ff", "fillStyle": "solid" }88```89- `roundness: { type: 3 }` for rounded corners9091**Ellipse**92```json93{ "type": "ellipse", "id": "e1", "x": 100, "y": 100, "width": 150, "height": 150 }94```9596**Diamond**97```json98{ "type": "diamond", "id": "d1", "x": 100, "y": 100, "width": 150, "height": 150 }99```100101**Label on shape (PREFERRED — no separate text element needed)**102```json103{ "type": "rectangle", "id": "r1", "x": 100, "y": 100, "width": 200, "height": 80,104 "label": { "text": "My Label", "fontSize": 20 } }105```106- Works on rectangle, ellipse, diamond107- Text auto-centers; container auto-resizes to fit108- Also works on arrows: `"label": { "text": "connects" }`109110**Standalone Text** (titles, annotations only)111```json112{ "type": "text", "id": "t1", "x": 150, "y": 50, "text": "Title", "fontSize": 24 }113```114- `x` is the LEFT edge. To center at position `cx`: set `x = cx - text.length × fontSize × 0.25`115116**Arrow**117```json118{ "type": "arrow", "id": "a1", "x": 300, "y": 150, "width": 150, "height": 0,119 "points": [[0,0],[150,0]], "endArrowhead": "arrow",120 "startBinding": { "elementId": "r1", "fixedPoint": [1, 0.5] },121 "endBinding": { "elementId": "r2", "fixedPoint": [0, 0.5] } }122```123- `points`: `[dx, dy]` offsets from element `x, y`124- `endArrowhead`: `null` | `"arrow"` | `"bar"` | `"dot"` | `"triangle"`125- `strokeStyle`: `"solid"` | `"dashed"` | `"dotted"`126- `fixedPoint` for bindings: top `[0.5,0]`, bottom `[0.5,1]`, left `[0,0.5]`, right `[1,0.5]`127128### Pseudo-Elements (not drawn — control behavior)129130**cameraUpdate** — sets the viewport131```json132{ "type": "cameraUpdate", "width": 800, "height": 600, "x": 0, "y": 0 }133```134- `x, y`: top-left corner of visible area (scene coordinates)135- **Must be 4:3 ratio**: 400×300, 600×450, 800×600, 1200×900, 1600×1200136- ALWAYS place a `cameraUpdate` as the **first element** to frame the diagram137- No `id` needed138139**delete** — removes elements by ID140```json141{ "type": "delete", "ids": "r1,a1,t2" }142```143- Comma-separated element IDs to remove144- Use when updating an existing diagram to remove elements before adding replacements145- Never reuse a deleted ID — assign new IDs to replacements146147## Camera Sizing Guide148149The diagram displays at ~700px width. Use these standard sizes:150151| Size | Width × Height | Use When |152|------|---------------|----------|153| S | 400 × 300 | 2–3 elements, close-up |154| M | 600 × 450 | Small diagram section |155| **L** | **800 × 600** | **Standard (default)** |156| XL | 1200 × 900 | Large overview |157| XXL | 1600 × 1200 | Very complex diagrams |158159**Font size rules:**160- Body text / labels: **minimum 16**161- Titles / headings: **minimum 20**162- Annotations: minimum 14 (use sparingly)163- At XL/XXL camera: increase minimums by ~4px164165**Element sizing rules:**166- Labeled rectangles/ellipses: minimum 120 × 60167- Leave 20–30px gaps between elements168169## Updating an Existing Diagram170171When the user asks to modify a diagram, you will receive the current elements in context. Respond with the complete updated elements array:172- Keep the same `id` for unchanged elements173- Modify fields on elements you want to change174- Omit elements you want to remove175- Add new elements with unique IDs not used before176177## Example: Flowchart178179```json180[181 { "type": "cameraUpdate", "width": 800, "height": 600, "x": 0, "y": 0 },182 { "type": "rectangle", "id": "el-1",183 "x": 300, "y": 60, "width": 160, "height": 60,184 "strokeColor": "#4a9eed", "backgroundColor": "#a5d8ff",185 "fillStyle": "solid", "roundness": { "type": 3 },186 "label": { "text": "Start", "fontSize": 18 } },187 { "type": "diamond", "id": "el-2",188 "x": 280, "y": 170, "width": 200, "height": 90,189 "strokeColor": "#f59e0b", "backgroundColor": "#fff3bf",190 "fillStyle": "solid",191 "label": { "text": "Decision?", "fontSize": 16 } },192 { "type": "arrow", "id": "el-3",193 "x": 380, "y": 120, "width": 0, "height": 50,194 "points": [[0,0],[0,50]], "endArrowhead": "arrow",195 "startBinding": { "elementId": "el-1", "fixedPoint": [0.5, 1] },196 "endBinding": { "elementId": "el-2", "fixedPoint": [0.5, 0] } },197 { "type": "rectangle", "id": "el-4",198 "x": 300, "y": 320, "width": 160, "height": 60,199 "strokeColor": "#22c55e", "backgroundColor": "#b2f2bb",200 "fillStyle": "solid", "roundness": { "type": 3 },201 "label": { "text": "End", "fontSize": 18 } },202 { "type": "arrow", "id": "el-5",203 "x": 380, "y": 260, "width": 0, "height": 60,204 "points": [[0,0],[0,60]], "endArrowhead": "arrow",205 "startBinding": { "elementId": "el-2", "fixedPoint": [0.5, 1] },206 "endBinding": { "elementId": "el-4", "fixedPoint": [0.5, 0] } }207]208```209210## Common Mistakes to Avoid211212- **Camera must use exact 4:3 ratios** — non-4:3 viewports cause distortion213- **Always start with cameraUpdate** — without it the viewport is unpredictable214- **No comments in element arrays** — `elements` must be valid JSON. Never add `//` or `/* */` comments inside the array; they break JSON parsing215- **Text contrast** — never use light gray on white. Minimum text color on white: `#757575`. For text on light fills use dark variants (`#15803d` not `#22c55e`)216- **Arrow labels need space** — long labels overflow short arrows; keep labels short or widen arrows217- **No emoji** — Excalidraw's font does not render emoji218- **Element overlap** — check that labels, boxes, and zone overlays don't stack on each other (minimum 20px gap)219- **Camera padding** — leave padding inside the camera frame; don't match camera size exactly to content size220221## UI Guidance (from tools-config)222223**Element Format:**224- Required: type, x, y, id225- Shapes (rectangle/ellipse/diamond): add width, height226- Arrows/lines: add width, height, points [[0,0],[dx,dy]]227- Text: add text, fontSize228- Use label field on shapes for centered text229- Connect shapes with arrow elements using points routing