Excalidraw
Use this skill when the user wants an editable diagram, not just a rendered image.
Typical requests:
- architecture or system diagrams
- flowcharts and process maps
- sequence diagrams
- concept maps and explainers
- hand-drawn style visuals that should stay editable in Excalidraw
Excalidraw files are plain JSON. The default deliverable is a *.excalidraw file in the workspace. The user can drag that file into excalidraw.com to view, edit, or export it.
Default Workflow
- Plan the diagram before writing JSON: title, nodes, connectors, groups, and rough canvas size.
- Write a valid Excalidraw
elementsarray. - Wrap the array in the standard file envelope.
- Save the result as
*.excalidraw. - If the user wants a shareable browser link, run:
node skills/excalidraw/scripts/upload.mjs diagram.excalidraw
The upload helper encrypts the diagram client-side and prints the Excalidraw share URL.
File Envelope
Use this shape unless you are editing an existing file and need to preserve more fields:
{
"type": "excalidraw",
"version": 2,
"source": "hybridclaw",
"elements": [],
"appState": {
"viewBackgroundColor": "#ffffff"
},
"files": {}
}
When editing an existing .excalidraw file, preserve appState, files, and any other existing top-level keys unless the user asked for a deliberate reset.
Rules
- Use Excalidraw JSON, not SVG or HTML, unless the user explicitly asked for another format.
- For labeled shapes or arrows, create a separate
textelement and bind it withcontainerIdplus the container'sboundElements. - Do not invent a
"label"property on rectangles, diamonds, ellipses, or arrows. Excalidraw ignores it. - Place a bound text element immediately after its container in the
elementsarray. - Use readable sizes:
fontSize16+ for normal labels, 20+ for titles, and at least120x60for labeled boxes. - Leave about
20-30pxof space between major elements. - Prefer short stable ids such as
api,text-api,arrow-api-db. - Avoid emoji and decorative Unicode. Stick to plain text that Excalidraw renders reliably.
- Default to a white background with dark text unless the user explicitly asks for dark mode.
- For arrows,
pointsare offsets relative to the arrow'sxandy.
Core Patterns
Labeled Rectangle
[
{
"type": "rectangle",
"id": "api",
"x": 120,
"y": 120,
"width": 220,
"height": 80,
"roundness": { "type": 3 },
"backgroundColor": "#a5d8ff",
"fillStyle": "solid",
"boundElements": [{ "id": "text-api", "type": "text" }]
},
{
"type": "text",
"id": "text-api",
"x": 130,
"y": 145,
"width": 200,
"height": 24,
"text": "API Service",
"fontSize": 20,
"fontFamily": 1,
"strokeColor": "#1e1e1e",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": "api",
"originalText": "API Service",
"autoResize": true
}
]
Arrow Between Shapes
{
"type": "arrow",
"id": "arrow-api-db",
"x": 340,
"y": 160,
"width": 180,
"height": 0,
"points": [[0, 0], [180, 0]],
"endArrowhead": "arrow",
"startBinding": { "elementId": "api", "fixedPoint": [1, 0.5] },
"endBinding": { "elementId": "db", "fixedPoint": [0, 0.5] }
}
Reference Files
- For palette and contrast guidance, read references/colors.md.
- For copy-pasteable diagram patterns, read references/examples.md.
- For dark-background diagrams, read references/dark-mode.md.
Anti-Patterns
- Do not cram many tiny nodes into one canvas when two simpler diagrams would read better.
- Do not put all shapes first and all text last; that usually breaks layering and bindings.
- Do not guess at Excalidraw-only properties you have not already seen in a working example.
- Do not replace an editable diagram request with a static PNG export unless the user asked for the export.