Writing pull requests
Standards for PR titles and descriptions in tldraw/tldraw.
PR title
Use semantic PR titles (Conventional Commits format):
<type>(<scope>): <description>
Types
feat- New featurefix- Bug fixdocs- Documentation onlyrefactor- Code change that neither fixes a bug nor adds a featureperf- Performance improvementtest- Adding or fixing testschore- Maintenance tasks
Scope (optional)
A noun describing the affected area: fix(editor):, feat(sync):, docs(examples):
Examples
feat(editor): add snap threshold configuration optionfix(arrows): correct binding behavior with rotated shapesdocs: update sync documentationrefactor(store): simplify migration system
PR body
Use this template:
<description paragraph>
### Change type
- [x] `bugfix` | `improvement` | `feature` | `api` | `other`
### Test plan
1. Step to test...
2. Another step...
- [ ] Unit tests
- [ ] End to end tests
### Release notes
- Brief description of changes for users
Description paragraph
Start with: "In order to X, this PR does Y."
- Keep it specific - avoid vague phrases like "improve user experience"
- Link related issues in the first paragraph
- Don't expect readers to also read the linked issue
Change type
- Tick exactly one type with
[x] - Delete unticked items
Test plan
- List manual testing steps if applicable
- Remove the numbered list if changes cannot be manually tested
- Tick checkboxes for included test types
Release notes
- Write brief notes describing user-facing changes
- Use imperative mood: "Add...", "Fix...", "Remove..."
- Omit this section entirely for internal work (CI, tooling, tests, etc.) that has no user-facing impact
API changes section
Include when changes affect api-report.md:
### API changes
- Added `Editor.newMethod()` for X
- Breaking! Removed `Editor.oldMethod()`
- Changed `Editor.method()` to accept optional `options` parameter
Code changes table
Create a table that includes net LOC changes for each of the following sections. The sum of all rows must match the total PR diff. Omit rows with no changes.
- Core code — SDK packages (
packages/) source, excluding tests and API reports - Tests — unit tests, e2e tests (
*.test.*,e2e/) - Automated files — generated files (e.g.
api-report.api.md, snapshots) - Documentation — docs site and examples (
apps/docs/,apps/examples/) - Apps — application code (
apps/dotcom/,apps/mcp-app/,apps/vscode/, etc.), excluding e2e tests - Templates — starter templates (
templates/) - Config/tooling — config files, lock files, lint config, CI, build scripts (
eslint.config.*,yarn.lock, etc.)
### Code changes
| Section | LOC change |
| --------------- | ---------- |
| Core code | +10 / -2 |
| Tests | +5 / -0 |
| Automated files | +0 / -1 |
| Documentation | +2 / -0 |
| Apps | +3 / -1 |
| Templates | +0 / -0 |
| Config/tooling | +1 / -0 |
Related issues
Search for and link relevant issues that this PR addresses.
Important
- Never include "Generated with Claude Code" unless the PR directly relates to Claude Code
- Never use title case for descriptions - use sentence case
- Never put yourself as co-author of any commits
- Always include an API changes section if the PR has changes to any api-report.md