Create Excalidraw diagram JSON files that make visual arguments. Use when the user wants to visualize workflows, architectures, protocols, or concepts.
43:T2dc8,
Generate .excalidraw JSON files that argue visually, not just display information.
Setup: if the user asks you to set up or verify the renderer for this skill, see README.md in this skill directory.
Before generating any diagram, read references/color-palette.md and use it as the single source of truth for colors, fills, strokes, text colors, fonts, and evidence artifact styling.
Diagrams should argue, not display.
The structure should carry meaning:
Run this test before committing to a layout:
Choose the right level first.
Use a simple conceptual diagram when:
Use a comprehensive technical diagram when:
For technical diagrams, include evidence artifacts.
Before drawing technical diagrams:
Include at least one of these when the diagram is technical:
The point is to show what the system actually looks like.
Comprehensive diagrams usually need three zoom levels:
Default to free-floating text.
Use a container only when:
Use free-floating text for titles, labels, annotations, and supporting detail.
Before generating JSON:
references/measure_text_bounds.py instead of guessing.references/element-templates.md and references/json-schema.md..excalidraw JSON.After generating JSON:
type: "excalidraw" and a non-empty elements array.references/render_excalidraw.py and read the PNG using the Read tool to visually inspect it. Do not skip this step. Do not assume the diagram is correct without looking at it.fontFamily: 1 (Virgil) elements remain; use 2 (Helvetica) or 3 (monospace)For technical diagrams with multiple boxes, repeated arrow routing, or likely iteration, prefer a generator-plus-validator workflow over hand-placing raw JSON.
Use deterministic layout when:
In deterministic mode:
.excalidraw from code or a structured layout spec rather than editing coordinates by hand.startBinding and endBinding whenever the connector represents a relationship between boxes. Do not ship free-floating arrows for box-to-box architecture flows.Repository hygiene rule:
/tmp or an inline command and leave the repo with only the requested diagram artifacts unless instructed otherwise.Use the Python helpers in references/geometry.py for exact text measurement, wrapping, container sizing, orthogonal routing, and preflight analysis. Use references/preflight_excalidraw.py to fail fast on overflow or overlap before rendering.
Minimum validation rules for deterministic mode:
Treat text collision detection as a geometric problem, not a visual guess.
Preferred model:
references/measure_text_bounds.py using the actual font family, font size, line height, and intended wrap width.Default precision:
Why:
If preflight cannot distinguish owned text from foreign overlap, treat that as a tooling gap and resolve it before trusting a "clean" result.
For technical architecture diagrams, connector quality is part of correctness, not just polish.
Treat these as defaults:
Red flags:
Render-and-inspect is still required, but it should confirm a layout that already passed mechanical checks. Do not treat PNG rendering alone as sufficient validation.
Do not guess text bounds for labels, cards, payload blocks, or evidence artifacts when those dimensions affect layout.
Use:
cd ~/.codex/skills/excalidraw-diagram/references
uv run python measure_text_bounds.py --text "Process" --font-family 3 --font-size 16
For multiline text, prefer stdin:
cd ~/.codex/skills/excalidraw-diagram/references
printf 'line one\nline two\n' | uv run python measure_text_bounds.py --stdin --font-family 3 --font-size 16
The script returns JSON with:
textWidthtextHeightreqWidthreqHeightUse reqWidth and reqHeight for the containing shape when you want padding included.
Use textWidth and textHeight for the text element itself.
This is deterministic relative to the local Playwright renderer environment. It is more reliable than heuristic character counting.
When fulfilling a diagram request:
.excalidraw file..png preview.references/color-palette.mdreferences/element-templates.mdreferences/json-schema.mdreferences/render_excalidraw.pyreferences/geometry.pyreferences/preflight_excalidraw.pyreferences/measure_text_bounds.py