@ogpallet/excalidraw-gen
v0.1.0
Published
CLI for generating sketch-style Excalidraw diagrams from natural-language prompts via Claude (Agent SDK). Includes linter, layout templates, few-shot examples, and pure-Node SVG/PNG render.
Maintainers
Readme
@ogpallet/excalidraw-gen
CLI for generating sketch-style Excalidraw diagrams from natural-language prompts via Claude — with a built-in style linter, 4 layout templates, few-shot guidance, and pure-Node SVG/PNG render.
"Структура портала Битрикс24: 4 рабочих группы, 2 проекта, 5 баз знаний"
↓
excalidraw-gen generate
↓
output.excalidraw → preview.svgUseful when you want a quick, on-brand sketch for a deck, doc, or wiki without opening the Excalidraw web editor.
Install
npm install -g @ogpallet/excalidraw-gen
# or use npx
npx @ogpallet/excalidraw-gen --helpRequires Node ≥ 20.19.0.
Quick Start
1. Authenticate (one-time, for generate only)
generate uses your Claude Max subscription via the Agent SDK — not an
Anthropic API key:
npm install -g @anthropic-ai/claude-code # if you don't have it
claude setup-token # opens browser, 1-year tokenPut the returned token in .env:
CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-...2. Generate a diagram
excalidraw-gen generate \
"Таймлайн внедрения Битрикс24 за 8 недель, 3 milestone" \
--template timeline \
--output timeline.excalidraw3. Render to SVG / PNG
excalidraw-gen render timeline.excalidraw --format svg -o timeline.svg
excalidraw-gen render timeline.excalidraw --format png --scale 2 -o timeline.pngOr open timeline.excalidraw directly on excalidraw.com
(drag-and-drop into the canvas) to edit.
Commands
| Command | What it does |
|---|---|
| generate <description> | LLM → skeleton → layout → convert → lint → retry-on-feedback. Needs OAuth token. |
| build <skeleton.json> | Convert a skeleton JSON directly to .excalidraw (no LLM). Pass - for stdin. |
| render <file.excalidraw> | Export to SVG or PNG (pure Node, no Chromium). |
| lint <file.excalidraw> | Style-check: palette, spacing, overlaps, fonts, arrow types. |
| list-templates | List the four layout templates. |
generate options
-t, --template <type> timeline | hierarchy | swim-lane | flow | auto (auto)
-p, --preset <name> pencil-dev | minimal (pencil-dev)
-o, --output <path> output file (./output.excalidraw)
--model <name> Claude model id (claude-sonnet-4-6)
--retry <n> max retry attempts on lint errors (2)
--no-lint skip lint + retry looprender options
--format <type> svg | png (svg)
-o, --output <path> output path (input with extension swapped)
--scale <n> PNG resolution mult (2)
--padding <n> pixels of padding (10)
--dark use dark theme (off)lint options
--json machine-readable report (exit 1 if any errors)Layout templates
Pass --template <name> to generate. Each template understands colorRole
groups and auto-arranges elements that don't have explicit x/y:
timeline— 8 stages in a horizontal row with milestones below.hierarchy— top-down tree, BFS levels from arrow connectivity.swim-lane— horizontal lanes grouped bycolorRole.flow— vertical stack, one column.
See worked examples in examples/.
Style presets
| Preset | Description |
|---|---|
| pencil-dev (default) | Warm 4-role palette (#1F4E79 / #7FB069 / #C0504D / #8C8C8C), Virgil font, hachure fills. Style guide: docs/excalidraw-guide.md §5. |
| minimal | Mono palette, Cascadia font. Useful for technical diagrams. |
Architecture (one screen)
description ─► LLM (Agent SDK, structured output)
│ skeleton (Zod-validated JSON)
▼
template.layoutHints (proceduralfills missing x/y)
│
▼
skeleton-to-excalidraw (element-builder + arrow-binder)
│ .excalidraw JSON
▼
linter (5 rules)
│ if errors → format feedback → retry LLM
▼
writeFile ─► render (optional, SVG/PNG)- Linter lives in
src/linter/— 5 rules covering palette size, spacing, overlaps, font count, arrow style. Returns{ pass, violations }. - Retry in
src/cli/commands/generate.ts— maxDEFAULTS.retryattempts; feedback string injected into the LLM's next user prompt. - Render in
src/render/index.ts— thin wrapper around@swiftlysingh/excalidraw-cli(pure Node, no Chromium).
Programmatic use
import { generateSkeleton } from "@ogpallet/excalidraw-gen/llm/client.js";
import { skeletonToExcalidraw } from "@ogpallet/excalidraw-gen/convert/skeleton-to-excalidraw.js";
import { PENCIL_DEV } from "@ogpallet/excalidraw-gen/convert/preset.js";
import { renderExcalidraw } from "@ogpallet/excalidraw-gen/render/index.js";
const { skeleton } = await generateSkeleton(
{ description: "...", presetName: "pencil-dev" },
{ model: "claude-sonnet-4-6" }
);
const { file } = skeletonToExcalidraw(skeleton, PENCIL_DEV);
const { content: svg } = await renderExcalidraw(file, { format: "svg" });Development
git clone https://github.com/ogpallet-cyber/excalidraw-gen.git
cd excalidraw-gen
npm install
npm test # vitest, 178 tests
npm run typecheck # tsc --noEmit
npm run build # tsc + copy few-shot assets to dist/License
MIT © 2026 ogpallet
