write-unit-tests — Claude Code skill for tldraw SDK tests
A skill that guides writing unit and integration tests in the tldraw repo: where test files belong, how to drive TestEditor, and which Vitest traps to avoid.
npx skills add tldraw/tldraw --skill write-unit-tests -a claude-codeWhat write-unit-tests does
This skill covers test authoring in the tldraw monorepo with Vitest. Tests run from workspace directories rather than the repository root. Core primitives, geometry and managers belong in packages/editor; anything that needs default shapes or tools goes in packages/tldraw.
It lays out file placement, points at existing suites to copy from, and explains the parts you won't learn by reading a neighboring test. Wheel and pinch events are batched, so a bare editor.dispatch() does nothing until you flush with editor.emit('tick', 16). Floating-point geometry comparisons need toCloselyMatchObject instead of toMatchObject, or rounding noise breaks the assertion. Animated code requires stubbing requestAnimationFrame at module scope, since vi.useFakeTimers() doesn't drive it.
The two TestEditor classes are package-specific and can't be swapped: the one in packages/editor ships without default shapes or tools. Import from the package under test. Every suite needs editor?.dispose() in afterEach, because otherwise subscriptions and timers leak into later tests in the same file. Spies on the editor must be restored with mockRestore(), and global state has to come back in finally or afterEach.
What it helps with
- write a first test for a new tldraw component
- decide which workspace a test belongs in
- fix a failing geometry assertion caused by rounding noise
- get animation tests working with requestAnimationFrame
- stop timer leaks between tests in one file
Example prompts for the agent
- Write a unit test for
Vec.tsnext to the file - Add an integration test for SelectTool in
packages/tldraw/src/test/ - Fix the failing test in
ArrowShapeUtil.test.ts
How to install write-unit-tests
1Skills CLI (Vercel)
npx skills add tldraw/tldraw --skill write-unit-tests -a claude-code2Manually: put the files in place
~/.claude/skills/write-unit-tests/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/write-unit-tests/
1Skills CLI (Vercel)
npx skills add tldraw/tldraw --skill write-unit-tests -a codex2Manually: put the files in place
.agents/skills/write-unit-tests/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add tldraw/tldraw --skill write-unit-tests -a cursor2Manually: put the files in place
.cursor/skills/write-unit-tests/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install tldraw/tldraw write-unit-tests2Manually: put the files in place
.github/skills/write-unit-tests/SKILL.md1Skills CLI (Vercel)
npx skills add tldraw/tldraw --skill write-unit-tests -a gemini-cli2Platform CLI
gemini skills install https://github.com/tldraw/tldraw --path skills/write-unit-testsManually: put the files in place
.devin/skills/write-unit-tests/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add tldraw/tldraw --skill write-unit-tests -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about write-unit-tests
How do I install write-unit-tests in Claude Code?
Run npx skills add tldraw/tldraw --skill write-unit-tests -a claude-code. The skill lands at ~/.claude/skills/write-unit-tests/SKILL.md.
What does write-unit-tests do?
It explains how to write Vitest unit and integration tests in the tldraw repository: file placement, TestEditor usage, and the gotchas around events, animations and mocks.
Why doesn't a wheel event apply after dispatch?
Wheel and pinch events are batched. Call editor.emit('tick', 16) after editor.dispatch(wheelEvent) so the event actually lands.