
Excalidraw
Generate valid Excalidraw JSON for architecture sketches, flow diagrams, and whiteboard-style visuals your agent can paste into Excalidraw.
Overview
Excalidraw is an agent skill most often used in Build (also Idea, Validate) that generates Excalidraw v2 JSON diagrams with bound labels and arrows for solo builders documenting systems.
Install
npx skills add https://github.com/agents365-ai/365-skills --skill excalidrawWhat is this skill?
- Excalidraw version-2 file skeleton with elements and appState ready to paste
- Copy-paste rectangle + bound label and arrow templates with binding rules
- Descriptive string IDs and section-namespaced seeds (100xxx) for stable layouts
- Palette and sizing/binding rules referenced from SKILL.md for generate-time correctness
- On-demand schema depth when SKILL.md rules are not enough for a full catalogue
- Excalidraw file skeleton uses type excalidraw at version 2
- Copy-paste templates use section-namespaced seeds in the 100xxx range
Adoption & trust: 679 installs on skills.sh; 8 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You need a shareable system diagram fast but hand-drawn specs or vague chat descriptions do not produce importable Excalidraw files.
Who is it for?
Solo builders who want agent-generated architecture or flow diagrams as structured Excalidraw output during planning and documentation.
Skip if: Teams that only need PNG mockups in Figma or who never use Excalidraw-compatible JSON in their workflow.
When should I use this skill?
You need Excalidraw JSON with correct bindings, templates, or full property values beyond the short rules in SKILL.md.
What do I get? / Deliverables
You get paste-ready Excalidraw JSON with correctly bound text and arrows you can drop into Excalidraw or docs.
- Excalidraw v2 JSON file or snippet with elements and appState
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Diagram artifacts usually ship with the product or spec during build, so docs is the canonical shelf even when you sketch earlier. Architecture and flow diagrams land in READMEs, ADRs, and handoff docs—exactly the docs subphase for solo builders documenting what they built.
Where it fits
Map competitor feature flows on a whiteboard-style diagram before committing to a build scope.
Sketch a clickable journey with labeled boxes and arrows to align on MVP screens.
Document auth service, gateway, and API boundaries in README architecture section.
Redraw deployment or data-flow diagram for PR review without re-explaining verbally.
How it compares
Structured diagram JSON from an agent skill—not a live Excalidraw MCP canvas or a generic ASCII-only sketch.
Common Questions / FAQ
Who is excalidraw for?
Indie and solo builders using Claude Code, Cursor, or Codex who document products with Excalidraw-style diagrams and want the agent to emit valid schema instead of guessing coordinates.
When should I use excalidraw?
During Idea research to map competitors or concepts, Validate when prototyping user flows, and Build docs when you need service diagrams, sequence-style layouts, or bound labels on boxes for READMEs and ADRs.
Is excalidraw safe to install?
Review the Security Audits panel on this Prism page for install risk and file-hash details before adding it to your agent bundle.
SKILL.md
READMESKILL.md - Excalidraw
# Excalidraw Schema Reference On-demand depth for the `excalidraw` skill. Read this when you need a copy-paste starting point or the full catalogue of a property's values. The core generate-time rules (binding, endpoints, sizing, arrow labels) live in `SKILL.md` — this file is the long tail, not a replacement. ## Copy-paste element templates All templates use descriptive string IDs and section-namespaced seeds (100xxx). Swap colors from the palette in `SKILL.md`. ### File skeleton ```json { "type": "excalidraw", "version": 2, "source": "claude-code", "elements": [], "appState": { "viewBackgroundColor": "#ffffff" } } ``` ### Rectangle component + bound label (the workhorse) ```json { "id": "auth_service", "type": "rectangle", "x": 100, "y": 100, "width": 160, "height": 60, "angle": 0, "strokeColor": "#1e40af", "backgroundColor": "#dbeafe", "fillStyle": "solid", "strokeWidth": 2, "roughness": 0, "opacity": 100, "seed": 100001, "boundElements": [{ "id": "label_auth", "type": "text" }] }, { "id": "label_auth", "type": "text", "text": "Auth Service", "fontSize": 20, "fontFamily": 2, "textAlign": "center", "verticalAlign": "middle", "strokeColor": "#1e293b", "seed": 100002, "containerId": "auth_service" } ``` ### Bound arrow between two shapes Both shapes must also list this arrow id in their own `boundElements`. ```json { "id": "arrow_gw_to_auth", "type": "arrow", "x": 260, "y": 130, "width": 200, "height": 0, "angle": 0, "strokeColor": "#475569", "backgroundColor": "transparent", "fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid", "roughness": 0, "opacity": 100, "seed": 100010, "points": [[0, 0], [200, 0]], "startBinding": { "elementId": "api_gateway", "gap": 5, "focus": 0 }, "endBinding": { "elementId": "auth_service", "gap": 5, "focus": 0 } } ``` ### Arrow with a bound label (Yes/No, message names) Label `width` must fit the **text**, never the arrow — a full-width label masks the whole line. ```json { "id": "arrow_valid_yes", "type": "arrow", "x": 200, "y": 300, "width": 0, "height": 120, "points": [[0, 0], [0, 120]], "seed": 100020, "strokeColor": "#475569", "strokeWidth": 2, "roughness": 0, "opacity": 100, "boundElements": [{ "id": "lbl_yes", "type": "text" }] }, { "id": "lbl_yes", "type": "text", "text": "Yes", "fontSize": 14, "width": 36, "fontFamily": 2, "strokeColor": "#1e293b", "seed": 100021, "containerId": "arrow_valid_yes" } ``` ### Start/end ellipse and decision diamond ```json { "id": "start", "type": "ellipse", "x": 60, "y": 40, "width": 140, "height": 70, "strokeColor": "#c2410c", "backgroundColor": "#fed7aa", "fillStyle": "solid", "strokeWidth": 2, "roughness": 0, "opacity": 100, "seed": 100030, "boundElements": [{ "id": "lbl_start", "type": "text" }] }, { "id": "decide", "type": "diamond", "x": 60, "y": 260, "width": 160, "height": 100, "strokeColor": "#854d0e", "backgroundColor": "#fef9c3", "fillStyle": "solid", "strokeWidth": 2, "roughness": 0, "opacity": 100, "seed": 100031, "boundElements": [{ "id": "lbl_decide", "type": "text" }] } ``` ### Swimlane zone + free-standing lane label Zone text is a **separate** top-left text element, never bound to the rectangle. ```json { "id": "lane_customer", "type": "rectangle", "x": 40, "y": 40, "width": 1000, "height": 200, "strokeColor": "#475569", "backgroundColor": "#f1f5f9", "fillStyle": "solid", "strokeStyle": "dashed", "strokeWidth": 2, "roughness": 0, "opacity": 30, "seed": 100040, "boundElements": null }, { "id": "lbl_lane_customer", "type": "text", "text": "Customer", "x": 56, "y": 52, "fontSize": 28, "fontFamily": 2, "strokeColor": "#334155", "seed": 100041, "containerId": null } ``` ### Mind-map line connector (not an arrow) ```json { "id": "line_center_a", "type": "line", "x": 500, "y": 300, "width": 180, "height": -120, "points": [[0, 0], [180, -120]], "strokeColor": "#475569", "strokeWidth": 2, "roughness": 0, "opacity": 100, "see