This file provides guidance to AI coding agents working in this repository.
- Use
yarn, notnpm, for repo commands. This repo uses Yarn workspaces and Yarn 4. - Run commands from the repo root unless a command explicitly says to run from a workspace.
- Never run bare
tsc; useyarn typecheckfrom the repo root. - Prefer targeted checks first. Avoid repo-wide test or e2e runs unless the change needs them.
- Keep changes scoped to the request and the affected package. Do not refactor unrelated code.
- Respect existing worktree changes. Do not revert user changes unless explicitly asked.
- Prefer editing existing files over creating new files. Do not add new documentation files unless requested.
- Use sentence case for headings, titles, labels, and documentation text.
This is the tldraw monorepo, an infinite canvas SDK for React applications. It is organized with Yarn workspaces.
Core packages:
packages/editor- foundational infinite canvas editor with no default shapes, tools, or UIpackages/tldraw- complete SDK with default UI, shapes, tools, and interactionspackages/store- reactive client-side database, persistence, and migrationspackages/tlschema- shape, binding, and record type definitions and validatorspackages/state- reactive signals librarypackages/syncandpackages/sync-core- multiplayer sync packagespackages/utilsandpackages/validate- shared utilities and validation helperspackages/assets- icons, fonts, translations, and bundled assets
Apps and examples:
apps/examples- SDK examples and demos; the main place for example developmentapps/docs- documentation site at tldraw.devapps/dotcom- tldraw.com app and workersapps/vscode- VS Code extensiontemplates- starter templates for supported frameworks
Requires Node >=22.12.0. Enable Corepack before installing dependencies:
npm i -g corepack && yarnDevelopment:
yarn dev- start the examples app at localhost:5420yarn dev-app- start the tldraw.com client appyarn dev-docs- start the docs siteyarn dev-vscode- start VS Code extension developmentyarn dev-template <template name>- run a template
Always run dev commands from the repo root. The root yarn dev runs each package's predev step, which generates build artifacts like packages/tldraw/tldraw.css. Running a per-workspace command (yarn workspace examples.tldraw.com dev) skips predev, so imports such as tldraw/tldraw.css fail to resolve. In a fresh git worktree, run yarn install first since worktrees start without node_modules.
Build:
yarn build- build all changed packages incrementallyyarn build-package- build SDK packages onlyyarn build-app- build the tldraw.com client appyarn build-docs- build the docs site
Testing:
yarn testin a workspace - run tests in watch modeyarn test runin a workspace - run tests onceyarn test run --grep "pattern"in a workspace - run matching testsyarn vitest- run all tests across the repo; slow, avoid unless necessaryyarn e2e- run examples e2e testsyarn e2e-dotcom- run tldraw.com e2e tests
Code quality:
yarn lint- lint the package or workspaceyarn lint-current- lint changed filesyarn typecheck- type check all packages and refresh assetsyarn format- format the repoyarn format-current- format changed filesyarn api-check- validate public API reports
- For narrow package changes, run the relevant workspace test first, for example
cd packages/tldraw && yarn test run --grep "SelectTool". - For changes that affect shared types, migrations, editor behavior, or cross-package contracts, run
yarn typecheckfrom the repo root. - For public API changes, run
yarn api-checkand include intentional API report updates. - For asset changes, run
yarn refresh-assetsoryarn typecheckso generated assets stay current. - For docs changes, run the narrow docs checks or docs build only when the change affects generated content, MDX behavior, or site structure.
- For e2e behavior changes, run the smallest relevant e2e suite and update snapshots only when behavior intentionally changed.
Reactive state:
- State is managed through
@tldraw/statesignals (Atom,Computed, and related primitives). - Editor state is observable and dependency-tracked. Avoid bypassing existing reactive patterns.
Shapes:
- Shape behavior lives in
ShapeUtilclasses. - Shape utils define geometry, rendering, handles, interactions, and SVG/export behavior.
- Add custom shape behavior through the established ShapeUtil patterns rather than one-off editor patches.
Tools:
- Tools are
StateNodestate machines. - Complex tools use child states for pointer, keyboard, tick, and transition behavior.
- Keep interaction logic close to the tool state that owns it.
Bindings:
- Shape relationships use binding records and
BindingUtilclasses. - Arrows and other connected shapes should update through binding utilities, not ad hoc shape mutation.
Store and schema:
- Store changes should respect migrations, validators, and schema versioning.
- Schema-affecting changes usually need updates in
packages/tlschemaand focused migration tests.
- Use
packages/editorfor core editor primitives, geometry, managers, and UI-free behavior. - Use
packages/tldrawfor default shapes, default tools, UI, and integration tests that need the full SDK. - Use
apps/examplesfor runnable SDK examples and demonstrations. - Use
apps/docs/contentfor documentation articles and release notes. - Use
apps/dotcom/clientfor tldraw.com frontend behavior. - Use
apps/dotcom/*-workerfor Cloudflare worker behavior. - Use
templatesfor starter project changes.
- Unit tests live alongside source files as
*.test.ts. - Integration tests commonly live in
packages/tldraw/src/test/. - E2E tests live in
apps/examples/e2e/andapps/dotcom/client/e2e/. - Test in
packages/tldrawwhen default shapes, tools, bindings, or UI are involved. - Test in
packages/editorfor core editor behavior that should not depend on default shapes or UI. - Prefer comparing whole objects in assertions when that gives a clearer failure than checking fields one by one.
- See
skills/write-unit-tests/andskills/write-e2e-tests/for detailed test patterns.
- Docs live in
apps/docs/content/. - Examples live in
apps/examples/src/examples/. - Example folders use lowercase kebab-case names.
- Example README frontmatter drives the examples site; keep titles and descriptions sentence case.
- Update docs or examples when an API or user-facing behavior changes.
- See
skills/write-docs/,skills/write-example/, andskills/write-release-notes/for task-specific guidance.
- Canonical agent skills live in
skills/. .agents/skillsis a symlink to../skillsfor generic agent compatibility..claude/skillsis a symlink to../skillsfor Claude compatibility. Keepskills/as the source of truth..cursor/skillsis a symlink to../skillsfor Cursor compatibility.- Skill folders use
skill-name/SKILL.mdwith YAML frontmatter containing at leastnameanddescription. - Put reusable scripts, references, and assets inside the relevant skill folder.
- Do not duplicate skill content for different agents; add compatibility pointers or symlinks instead.
- See
skills/skill-creator/before creating or restructuring skills. - User-facing workflow skills include
skills/pr/,skills/issue/,skills/take/,skills/commit-changes/, andskills/clean-copy/.
TypeScript:
- Follow existing file-local style and abstractions.
- Use workspace types and helpers rather than duplicating definitions.
- Keep public API changes deliberate and reflected in API reports.
- Avoid boolean or ambiguous positional options in new APIs when a named object or enum would make call sites clearer.
React and UI:
- Follow existing component patterns in the relevant app or package.
- Keep user-facing text concise and sentence case.
- Avoid broad UI rewrites when a focused component change is enough.
Generated files:
- Do not hand-edit generated assets, API reports, or schemas unless the repo already expects that file to be edited directly.
- Run the owning generator command when generated output needs to change.
Dependencies:
- Keep dependencies workspace-appropriate.
- If changing dependency manifests or lockfiles, make sure the lockfile update is intentional and included.
- Use sentence case for Markdown headings, UI labels, docs titles, PR titles, and issue titles.
- Capitalize proper nouns, acronyms, and code names normally, for example
PostgreSQL,WebSocket, andNodeShapeUtil. - Use direct, concrete language.
- Do not include AI attribution in commits, PR descriptions, issues, docs, release notes, or generated written content.
- Keep commits focused when asked to commit.
- Use semantic PR titles for pull requests:
<type>(<scope>): <description>. - Never add yourself or an AI tool as a co-author.
- See
skills/pr/andskills/issue/for GitHub workflows, andskills/write-pr/andskills/write-issue/for repository content standards.