excalidraw
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseExcalidraw Skill
Excalidraw 操作技能
Step 0: Setup
步骤0:环境配置
Load companion skills when needed
根据需求加载配套技能
- Drawing or styling a diagram → load (colors, sizing, anti-patterns)
excalidraw-design-guide - Building a multi-element diagram or reviewing one → load (planning, progressive drawing, review checklist)
excalidraw-workflow - Just checking status, exporting, or running a single command → no companion skills needed
- 绘制或设计图表 → 加载(包含颜色、尺寸、反模式相关内容)
excalidraw-design-guide - 构建或审查多元素图表 → 加载(包含规划、渐进式绘制、审查清单相关内容)
excalidraw-workflow - 仅检查状态、导出内容或执行单个命令 → 无需加载配套技能
Check if canvas is running
检查画布是否运行
bash
excalidraw statusReturns if running.
{"status":"healthy","elements_count":N}bash
excalidraw status如果画布正在运行,将返回。
{"status":"healthy","elements_count":N}Start canvas if not running
若画布未运行则启动
bash
excalidraw serve --port 3000Open in a browser (required for screenshot/image export).
http://localhost:3000bash
excalidraw serve --port 3000在浏览器中打开(截图/图片导出功能需要此操作)。
http://localhost:3000Install CLI (one-time)
安装CLI(仅需一次)
bash
bun add -g github:opencoredev/excalidraw-clibash
bun add -g github:opencoredev/excalidraw-cliGlobal URL override
全局URL覆盖
bash
export EXCALIDRAW_URL=http://localhost:3000All commands respect . Override per-command with .
EXCALIDRAW_URL--url <url>bash
export EXCALIDRAW_URL=http://localhost:3000所有命令都会遵循配置。也可以通过参数为单个命令指定URL。
EXCALIDRAW_URL--url <url>⚡ Draw Element by Element — Don't Make the User Wait
⚡ 逐个绘制元素——不要让用户等待
Never batch everything into one command. Create each element individually so the user sees every shape appear on canvas and can redirect if something is wrong.
bash
undefined切勿将所有操作批量执行成一个命令。逐个创建每个元素,这样用户可以看到每个形状实时出现在画布上,若出现问题可及时调整。
bash
undefinedEach element is its own call — user sees it appear immediately
每个元素单独调用——用户可立即看到元素出现
excalidraw create --type rectangle --id svc-a --x 100 --y 100 --width 160 --height 60 --text "Service A"
excalidraw viewport --fit
excalidraw create --type rectangle --id svc-b --x 100 --y 240 --width 160 --height 60 --text "Service B"
excalidraw viewport --fit
excalidraw create --type arrow --x 0 --y 0 --start svc-a --end svc-b
excalidraw viewport --fit
**Order**: zones/containers first → nodes one by one → arrows one by one → detail labels last.
**Rule**: your first tool call must be a draw command — no exceptions. Do not reason through the whole diagram before starting. Draw the first element, then think of the next one while it renders.
**`excalidraw batch` is only for** tightly interdependent elements that must exist together. Everything else: one `create` at a time.
---excalidraw create --type rectangle --id svc-a --x 100 --y 100 --width 160 --height 60 --text "Service A"
excalidraw viewport --fit
excalidraw create --type rectangle --id svc-b --x 100 --y 240 --width 160 --height 60 --text "Service B"
excalidraw viewport --fit
excalidraw create --type arrow --x 0 --y 0 --start svc-a --end svc-b
excalidraw viewport --fit
**绘制顺序**:先绘制区域/容器 → 逐个绘制节点 → 逐个绘制箭头 → 最后添加细节标签。
**规则**:你的第一个工具调用必须是绘制命令——无例外。不要在开始绘制前就构思完整图表。先绘制第一个元素,在它渲染的同时再思考下一个元素。
**`excalidraw batch`仅适用于**必须同时存在的高度关联元素。其他所有元素:都要逐个使用`create`命令创建。
---Inline Self-Check (do this mentally before EVERY element)
内联自检(在创建每个元素前在脑中完成)
Before issuing each , ask yourself:
excalidraw create- Will the text fit? Count characters in the label. Apply: . When in doubt, go wider — truncation looks worse than a wide box.
width = max(160, charCount * 11 + 40) - Am I drawing shapes before arrows? Arrows must always be created AFTER both their source and target shapes exist. Never draw an arrow to a shape that doesn't exist yet — it won't bind and will float or overdraw.
- Is there enough gap? At least 60px between adjacent shapes, 80px between tiers. Cramped = arrows cross through boxes.
Fix it now, not later. If you realize a shape is too narrow after creating it, immediately before moving on.
excalidraw update <id> --width <wider>在执行每个命令前,问自己:
excalidraw create- 文本是否能容纳? 统计标签的字符数。应用公式:。拿不准时就设置更宽——文本截断比宽盒子更影响体验。
width = max(160, charCount * 11 + 40) - 我是否先绘制了形状再绘制箭头? 箭头必须在其源形状和目标形状都创建完成后再绘制。永远不要向不存在的形状绘制箭头——这样箭头无法绑定,会漂浮或覆盖其他元素。
- 间距是否足够? 相邻形状之间至少保留60px间距,不同层级之间至少保留80px间距。过于拥挤会导致箭头穿过盒子。
立即修正,不要拖延。如果创建后发现形状太窄,在进行下一步前立即执行。
excalidraw update <id> --width <更宽的数值>Sizing formula
尺寸计算公式
- Shape width: pixels — the
max(160, charCount * 11 + 40)is mandatory padding, never skip it+40 - Multi-word labels: measure the longest single word, not total chars:
max(160, longestWord * 11 + 80) - Shape height: 60px single-line, 80px two-line, 100px three-line
- Background zones: 60px padding on all sides around contained elements (not 50)
- Arrow minimum gap: 80px between shapes — if shapes are closer, arrows will overdraw the border
- 形状宽度:像素——
max(160, charCount * 11 + 40)是必填内边距,切勿省略+40 - 多词标签:测量最长的单个单词,而非总字符数:
max(160, longestWord * 11 + 80) - 形状高度:单行文本60px,两行80px,三行100px
- 背景区域:包含元素的四周需保留60px内边距(而非50px)
- 箭头最小间距:形状之间至少80px——如果形状间距更近,箭头会覆盖边框
Arrow binding rules (prevents overline)
箭头绑定规则(避免覆盖)
- Always use — never use raw coordinates to connect shapes
--start <id> --end <id> - Create shapes first, arrows second — every time, no exceptions
- If an arrow appears to pass through a box, the shape was too close or the arrow wasn't bound: delete and recreate with proper /
--start--end
- 始终使用——永远不要使用原始坐标连接形状
--start <id> --end <id> - 先创建形状,再创建箭头——每次都要遵守,无例外
- 如果箭头看起来穿过了盒子,说明形状间距太近或箭头未正确绑定:删除箭头并使用正确的/
--start参数重新创建--end
Quality Gate (only if something looks off)
质量检查(仅当看起来有问题时执行)
If you suspect a problem after a section of elements:
bash
excalidraw describe # spot-check element list and IDs
excalidraw viewport --fitDon't run this after every single element — just when something feels wrong.
如果在创建一部分元素后怀疑存在问题:
bash
excalidraw describe # 抽查元素列表和ID
excalidraw viewport --fit不要在每个元素创建后都执行此操作——仅在感觉有问题时使用。
Workflow: Draw a Diagram
工作流:绘制图表
Recommended order
推荐顺序
- — load design best practices
excalidraw guide - Plan coordinate grid on paper first (prevents overlap)
- — start fresh (optional)
excalidraw clear - — create all shapes and arrows at once
excalidraw batch diagram.json - — zoom to fit all elements
excalidraw viewport --fit - Run Quality Gate above
- —— 加载设计最佳实践
excalidraw guide - 先在纸上规划坐标网格(避免重叠)
- —— 清空画布重新开始(可选)
excalidraw clear - —— 一次性创建所有形状和箭头
excalidraw batch diagram.json - —— 缩放至适配所有元素
excalidraw viewport --fit - 执行上述质量检查步骤
Batch JSON format
批量JSON格式
Create a file :
diagram.jsonjson
{
"elements": [
{
"id": "svc-a",
"type": "rectangle",
"x": 100, "y": 100,
"width": 160, "height": 60,
"label": {"text": "Service A"},
"strokeColor": "#1971c2",
"backgroundColor": "#a5d8ff"
},
{
"id": "svc-b",
"type": "rectangle",
"x": 100, "y": 240,
"width": 160, "height": 60,
"label": {"text": "Service B"},
"strokeColor": "#2f9e44",
"backgroundColor": "#b2f2bb"
},
{
"type": "arrow",
"x": 0, "y": 0,
"start": {"id": "svc-a"},
"end": {"id": "svc-b"},
"label": {"text": "HTTP"}
}
]
}Then run:
excalidraw batch diagram.jsonCritical: Use / to bind arrows.
Critical: Use for shape text (not ).
For standalone text elements (), use directly.
"start": {"id": "..."}"end": {"id": "..."}"label": {"text": "..."}"text": "...""type": "text""text": "..."创建文件:
diagram.jsonjson
{
"elements": [
{
"id": "svc-a",
"type": "rectangle",
"x": 100, "y": 100,
"width": 160, "height": 60,
"label": {"text": "Service A"},
"strokeColor": "#1971c2",
"backgroundColor": "#a5d8ff"
},
{
"id": "svc-b",
"type": "rectangle",
"x": 100, "y": 240,
"width": 160, "height": 60,
"label": {"text": "Service B"},
"strokeColor": "#2f9e44",
"backgroundColor": "#b2f2bb"
},
{
"type": "arrow",
"x": 0, "y": 0,
"start": {"id": "svc-a"},
"end": {"id": "svc-b"},
"label": {"text": "HTTP"}
}
]
}然后执行:
excalidraw batch diagram.json关键注意事项:使用 / 来绑定箭头。
关键注意事项:为形状文本使用(而非)。
对于独立文本元素(),直接使用。
"start": {"id": "..."}"end": {"id": "..."}"label": {"text": "..."}"text": "...""type": "text""text": "..."Command Reference
命令参考
Server management
服务器管理
bash
excalidraw status # Health check
excalidraw serve --port 3000 # Start canvas server (blocks)
excalidraw serve --port 3000 --host 0.0.0.0 # Bind to all interfacesbash
excalidraw status # 健康检查
excalidraw serve --port 3000 # 启动画布服务器(阻塞式)
excalidraw serve --port 3000 --host 0.0.0.0 # 绑定到所有网络接口Element CRUD
元素增删改查(CRUD)
bash
excalidraw create --type rectangle --x 100 --y 100 --width 160 --height 60 --text "Box"
excalidraw create --type arrow --x 0 --y 0 --start <id> --end <id>
excalidraw create --type text --x 50 --y 50 --text "Title" --font-size 24
excalidraw update <id> --text "New Label" --stroke-color "#e03131"
excalidraw update <id> --x 200 --y 300 --width 200 --height 80
excalidraw delete <id>
excalidraw get <id> # Get single element
excalidraw query # Get all elements
excalidraw query --type rectangle # Filter by typebash
excalidraw create --type rectangle --x 100 --y 100 --width 160 --height 60 --text "Box"
excalidraw create --type arrow --x 0 --y 0 --start <id> --end <id>
excalidraw create --type text --x 50 --y 50 --text "Title" --font-size 24
excalidraw update <id> --text "New Label" --stroke-color "#e03131"
excalidraw update <id> --x 200 --y 300 --width 200 --height 80
excalidraw delete <id>
excalidraw get <id> # 获取单个元素
excalidraw query # 获取所有元素
excalidraw query --type rectangle # 按类型过滤Batch operations
批量操作
bash
excalidraw batch diagram.json # From file
cat diagram.json | excalidraw batch # From stdin
excalidraw clear # Remove all elementsbash
excalidraw batch diagram.json # 从文件加载
cat diagram.json | excalidraw batch # 从标准输入加载
excalidraw clear # 删除所有元素Scene I/O
场景导入导出
bash
excalidraw export # Print .excalidraw JSON to stdout
excalidraw export --out scene.excalidraw # Write to file
excalidraw import scene.excalidraw # Import (replaces canvas)
excalidraw import scene.excalidraw --mode merge # Merge with existing
excalidraw snapshot v1 # Save named snapshot
excalidraw restore v1 # Restore snapshotbash
excalidraw export # 将.excalidraw JSON输出到标准输出
excalidraw export --out scene.excalidraw # 写入到文件
excalidraw import scene.excalidraw # 导入(替换当前画布)
excalidraw import scene.excalidraw --mode merge # 与现有内容合并
excalidraw snapshot v1 # 保存命名快照
excalidraw restore v1 # 恢复快照Viewport & visualization
视口与可视化
bash
excalidraw viewport --fit # Zoom to fit all elements
excalidraw viewport --element <id> # Center on element
excalidraw viewport --zoom 1.5 # Set zoom level
excalidraw describe # List all elements (text summary)
excalidraw screenshot # Capture canvas (requires browser)
excalidraw screenshot --format svg --out diagram.svgbash
excalidraw viewport --fit # 缩放至适配所有元素
excalidraw viewport --element <id> # 居中显示指定元素
excalidraw viewport --zoom 1.5 # 设置缩放级别
excalidraw describe # 列出所有元素(文本摘要)
excalidraw screenshot # 捕获画布截图(需要浏览器)
excalidraw screenshot --format svg --out diagram.svgLayout tools
布局工具
bash
excalidraw align id1 id2 id3 --alignment left # Align left edges
excalidraw align id1 id2 id3 --alignment top # Align top edges
excalidraw align id1 id2 id3 --alignment center # Center horizontally
excalidraw align id1 id2 id3 --alignment middle # Center vertically
excalidraw distribute id1 id2 id3 --direction horizontal
excalidraw distribute id1 id2 id3 --direction vertical
excalidraw group id1 id2 id3 # Group elements
excalidraw ungroup <groupId> # Ungroup
excalidraw duplicate id1 id2 --dx 20 --dy 20
excalidraw lock id1 id2 # Lock (prevent UI edits)
excalidraw unlock id1 id2bash
excalidraw align id1 id2 id3 --alignment left # 左对齐边缘
excalidraw align id1 id2 id3 --alignment top # 顶部对齐
excalidraw align id1 id2 id3 --alignment center # 水平居中
excalidraw align id1 id2 id3 --alignment middle # 垂直居中
excalidraw distribute id1 id2 id3 --direction horizontal
excalidraw distribute id1 id2 id3 --direction vertical
excalidraw group id1 id2 id3 # 组合元素
excalidraw ungroup <groupId> # 取消组合
excalidraw duplicate id1 id2 --dx 20 --dy 20
excalidraw lock id1 id2 # 锁定(防止UI编辑)
excalidraw unlock id1 id2Export & sharing
导出与分享
bash
excalidraw url # Export as encrypted excalidraw.com URL
excalidraw mermaid diagram.mmd # Convert Mermaid to Excalidraw
echo "graph TD; A-->B" | excalidraw mermaidbash
excalidraw url # 导出为加密的excalidraw.com链接
excalidraw mermaid diagram.mmd # 将Mermaid转换为Excalidraw格式
echo "graph TD; A-->B" | excalidraw mermaidDesign guide
设计指南
bash
excalidraw guide # Print color palette, sizing, layout rulesbash
excalidraw guide # 打印调色板、尺寸、布局规则Element Types Reference
元素类型参考
| Type | Required | Notes |
|---|---|---|
| rectangle | x, y, width, height | Use |
| ellipse | x, y, width, height | Use |
| diamond | x, y, width, height | Use |
| text | x, y, text | Standalone text; use |
| arrow | x, y | Bind with |
| line | x, y, points | Manual points array [[x,y],[x,y]] |
| freedraw | x, y, points | Freehand path |
| 类型 | 必填参数 | 说明 |
|---|---|---|
| rectangle | x, y, width, height | 标签使用 |
| ellipse | x, y, width, height | 标签使用 |
| diamond | x, y, width, height | 标签使用 |
| text | x, y, text | 独立文本元素;使用 |
| arrow | x, y | 使用 |
| line | x, y, points | 手动指定点数组 [[x,y],[x,y]] |
| freedraw | x, y, points | 手绘路径 |
Common Patterns
常见模式
Architecture diagram
架构图
json
{
"elements": [
{"id":"zone","type":"rectangle","x":40,"y":40,"width":500,"height":400,
"backgroundColor":"#e9ecef","strokeColor":"#868e96","opacity":50,
"label":{"text":"Backend"}},
{"id":"api","type":"rectangle","x":80,"y":100,"width":160,"height":60,
"strokeColor":"#1971c2","backgroundColor":"#a5d8ff","label":{"text":"API Gateway"}},
{"id":"db","type":"rectangle","x":80,"y":260,"width":160,"height":60,
"strokeColor":"#0c8599","backgroundColor":"#99e9f2","label":{"text":"Database"}},
{"type":"arrow","x":0,"y":0,"start":{"id":"api"},"end":{"id":"db"},
"label":{"text":"SQL"}}
]
}json
{
"elements": [
{"id":"zone","type":"rectangle","x":40,"y":40,"width":500,"height":400,
"backgroundColor":"#e9ecef","strokeColor":"#868e96","opacity":50,
"label":{"text":"Backend"}},
{"id":"api","type":"rectangle","x":80,"y":100,"width":160,"height":60,
"strokeColor":"#1971c2","backgroundColor":"#a5d8ff","label":{"text":"API Gateway"}},
{"id":"db","type":"rectangle","x":80,"y":260,"width":160,"height":60,
"strokeColor":"#0c8599","backgroundColor":"#99e9f2","label":{"text":"Database"}},
{"type":"arrow","x":0,"y":0,"start":{"id":"api"},"end":{"id":"db"},
"label":{"text":"SQL"}}
]
}Flowchart
流程图
json
{
"elements": [
{"id":"start","type":"ellipse","x":160,"y":40,"width":120,"height":60,
"strokeColor":"#2f9e44","backgroundColor":"#b2f2bb","label":{"text":"Start"}},
{"id":"step1","type":"rectangle","x":140,"y":160,"width":160,"height":60,
"strokeColor":"#1971c2","backgroundColor":"#a5d8ff","label":{"text":"Process Data"}},
{"id":"decide","type":"diamond","x":140,"y":280,"width":160,"height":80,
"strokeColor":"#e8590c","backgroundColor":"#ffd8a8","label":{"text":"Valid?"}},
{"type":"arrow","x":0,"y":0,"start":{"id":"start"},"end":{"id":"step1"}},
{"type":"arrow","x":0,"y":0,"start":{"id":"step1"},"end":{"id":"decide"}}
]
}json
{
"elements": [
{"id":"start","type":"ellipse","x":160,"y":40,"width":120,"height":60,
"strokeColor":"#2f9e44","backgroundColor":"#b2f2bb","label":{"text":"Start"}},
{"id":"step1","type":"rectangle","x":140,"y":160,"width":160,"height":60,
"strokeColor":"#1971c2","backgroundColor":"#a5d8ff","label":{"text":"Process Data"}},
{"id":"decide","type":"diamond","x":140,"y":280,"width":160,"height":80,
"strokeColor":"#e8590c","backgroundColor":"#ffd8a8","label":{"text":"Valid?"}},
{"type":"arrow","x":0,"y":0,"start":{"id":"start"},"end":{"id":"step1"}},
{"type":"arrow","x":0,"y":0,"start":{"id":"step1"},"end":{"id":"decide"}}
]
}Iterative Refinement Loop
迭代优化循环
excalidraw batch diagram.json
→ excalidraw describe (verify elements exist with correct IDs)
→ excalidraw viewport --fit (auto-fit view)
→ excalidraw screenshot --out /tmp/check.png (visual check)
→ [if issues] excalidraw update <id> --width 200 --height 80
→ excalidraw screenshot --out /tmp/check2.png (re-verify)
→ [all good] doneexcalidraw batch diagram.json
→ excalidraw describe (验证元素是否存在且ID正确)
→ excalidraw viewport --fit (自动适配视口)
→ excalidraw screenshot --out /tmp/check.png (可视化检查)
→ [若有问题] excalidraw update <id> --width 200 --height 80
→ excalidraw screenshot --out /tmp/check2.png (重新验证)
→ [无问题] 完成Troubleshooting
故障排除
- Server unreachable: Run . If error →
excalidraw statusexcalidraw serve --port 3000 - Screenshot fails: Open in a browser first
http://localhost:3000 - Arrow not connecting: Use not coordinate points
"start": {"id": "..."} - Label not showing: Use for shapes (not
"label": {"text": "..."})"text": "..." - Elements lost after restart: Use before stopping
excalidraw export --out backup.excalidraw
- 服务器无法访问:执行。若报错 → 执行
excalidraw statusexcalidraw serve --port 3000 - 截图失败:先在浏览器中打开
http://localhost:3000 - 箭头未连接:使用而非坐标点
"start": {"id": "..."} - 标签未显示:为形状使用(而非
"label": {"text": "..."})"text": "..." - 重启后元素丢失:停止前执行进行备份
excalidraw export --out backup.excalidraw