excalidraw-tools
CLI tools and Python library for creating, editing, validating, and
rendering Excalidraw diagrams
programmatically.
Designed to be used by LLM agents or directly from the command line. The
tools enforce correct Excalidraw JSON structure --- roundness values,
seed generation, index ordering, arrow bindings --- so you never have to
write raw .excalidraw JSON by hand.
Install
uv tool install excalidraw-tools # CLI only
uv tool install "excalidraw-tools[preview]" # CLI + matplotlib renderer
Or with pip:
pip install excalidraw-tools
pip install "excalidraw-tools[preview]"
Agent skill
This repo ships an Agent Skill in
skills/excalidraw/. The skill teaches LLM agents how to use the
excalidraw-tools CLI to create and iterate on diagrams through a
structured workflow: build from spec, validate, render, show preview,
iterate on feedback.
The skill follows the open SKILL.md
standard and works with any
compatible agent, including:
To use the skill, point your agent at the skills/excalidraw/ directory
using whatever mechanism it supports (e.g., Claude Code plugin, Cursor
skills directory, --add-dir, etc.).
Quick start
Build a diagram from a spec
Write a compact JSON spec:
{
"seed": 42,
"nodes": [
{ "id": "client", "type": "ellipse", "label": "Client", "x": 120, "y": 80, "width": 200, "height": 80 },
{ "id": "api", "type": "rectangle", "label": "API", "x": 120, "y": 260, "width": 200, "height": 80 }
],
"edges": [
{ "from": "client", "to": "api", "fromEdge": "bottom", "toEdge": "top", "label": "HTTPS" }
]
}
Generate the diagram:
excalidraw-tools build --spec diagram.spec.json --output diagram.excalidraw
excalidraw-tools validate diagram.excalidraw
Edit an existing diagram
excalidraw-tools edit move --input diagram.excalidraw --label "API" --dx 200 --dy 0
excalidraw-tools edit relabel --input diagram.excalidraw --label "API" --text "Gateway"
excalidraw-tools edit recolor --input diagram.excalidraw --label "Gateway" --stroke "#1971c2" --background "#a5d8ff"
excalidraw-tools edit delete --input diagram.excalidraw --label "Gateway"
excalidraw-tools edit add-box --input diagram.excalidraw --label "Cache" --x 400 --y 260
excalidraw-tools edit connect --input diagram.excalidraw --from-label "Client" --to-label "Cache"
Render a preview
excalidraw-tools preview diagram.excalidraw --output diagram.png
For browser-accurate rendering with proper font support, see the
Self-hosted Excalidraw stack section
below.
CLI reference
| Command | Description |
|---|
excalidraw-tools build | Build .excalidraw from a spec JSON |
excalidraw-tools edit <sub> | Edit in place: move, relabel, recolor, delete, add-box, connect |
excalidraw-tools validate | Schema and linkage validation |
excalidraw-tools preview | Approximate PNG via matplotlib |
excalidraw-tools sync-spec | Derive/update a .spec.json sidecar from a diagram |
excalidraw-tools golden-check | Regression test against bundled golden fixture |
Run any command with --help for full options.
Self-hosted Excalidraw stack
This repo includes a Docker Compose stack that runs a fully self-hosted
Excalidraw instance with real-time collaboration, persistent share
links, and a high-fidelity rendering API. No diagram data is sent to
third-party services.
Architecture
Collaboration and storage path:
┌──────────────┐ HTTP ┌──────────────────┐
│ Browser │◄───────────►│ Excalidraw UI │ :3000
│ │ │ (nginx + JS) │
│ │ WebSocket ├──────────────────┤
│ │◄───────────►│ excalidraw-room │ :3002
│ │ │ (WS relay) │
│ │ HTTP ├──────────────────┤
│ │◄───────────►│ storage-backend │ :3003
│ │ │ (blob store) │
└──────────────┘ └──────────────────┘
Rendering path: