Create user-facing changelog entries using changesets for versioned releases
feat, fix, or user-facing refactorChangesets are a way to manage versioning and changelogs for packages and projects. Each changeset is a small file describing a change that will appear in the changelog when the package is released.
| Aspect | Commit Message | Changeset Message |
|---|---|---|
| Audience | Developers, code reviewers | End users, product consumers |
| Focus | What changed in the code | What users will experience |
| Detail | Can be technical | Must be user-friendly |
| Purpose | Code history tracking | Release notes, changelog |
| Example | refactor: extract retry logic into separate class | Fixed connection reliability issues |
Changesets are markdown files in .changeset/ directory with this structure:
---
"package-name": patch
---
Brief description of the change from user perspective
| Level | When to use | Examples |
|---|---|---|
major | Breaking changes that affect existing usage | Removed deprecated API, Changed parameter order, Renamed core methods |
minor | New features, enhancements (backward compatible) | Added new endpoint, New configuration option, Enhanced performance |
patch | Bug fixes, minor improvements (backward compatible) | Fixed validation error, Corrected calculation, Improved error message |
Use these categories to classify changes for users:
| Category | Commit Types | User Impact | Example |
|---|---|---|---|
| Added | feat | New features or capabilities | Added retry mechanism for failed operations |
| Changed | feat, refactor, perf | Modified existing behavior | Improved dashboard loading speed |
| Deprecated | feat | Features marked for future removal | Authentication v1 API will be removed in next major version |
| Removed | feat, refactor | Features that no longer exist | Removed legacy export format |
| Fixed | fix | Bug fixes and corrections | Fixed incorrect totals in reports |
| Security | fix, feat | Security-related fixes or improvements | Resolved authentication bypass vulnerability |
Does the project use changesets?
├─ No -> STOP (this skill doesn't apply)
└─ Yes -> Continue
Does the change affect end users?
├─ No -> Examples:
│ • Internal refactoring with no behavior change
│ • Test additions/updates
│ • Documentation updates
│ • Build script changes
│ • Code style changes
│ → SKIP changeset
│
└─ Yes -> Continue
What is the commit type?
├─ feat -> CREATE changeset (likely minor or major)
├─ fix -> CREATE changeset (patch)
├─ refactor -> Does it change user-visible behavior?
│ ├─ Yes -> CREATE changeset (patch or minor)
│ └─ No -> SKIP changeset
├─ perf -> Is improvement noticeable to users?
│ ├─ Yes -> CREATE changeset (patch or minor)
│ └─ No -> SKIP changeset
└─ docs, test, chore, style, ci, build
-> SKIP changeset (internal only)
Check for these indicators:
# Check for .changeset directory
ls -la .changeset/
# Check for changesets in package.json
grep "changesets" package.json
# Check for changeset config
cat .changeset/config.json
If none exist → Skip this skill, project doesn't use changesets
Ask yourself:
If all answers are "No" → Skip changeset
Breaking change (incompatible with previous version)?
└─ Yes -> major
New feature or enhancement (backward compatible)?
└─ Yes -> minor
Bug fix or minor improvement (backward compatible)?
└─ Yes -> patch
Choose the most appropriate:
Good practices:
Bad practices:
Use changesets CLI - it guides you through the process:
npx changeset add
The CLI will:
@tinyfwk/core)major, minor, or patchThis is the recommended approach as it ensures proper format and naming conventions.
---
"@tinyfwk/core": minor
---
Added InMemoryCommandBus.java implementing CommandBus interface with
handler registration and middleware pipeline execution
---
"@tinyfwk/core": minor
---
Added command bus with middleware support for extensible request processing
---
"@tinyfwk/api": patch
---
Fixed NullPointerException in QueryHandlerExecutor.java line 45 by adding
null check before handler.handle() invocation
---
"@tinyfwk/api": patch
---
Fixed crash when processing queries without registered handlers
---
"@tinyfwk/core": patch
---
Refactored Pipeline.java to use ArrayList instead of LinkedList reducing
iteration overhead by 15ms on average
---
"@tinyfwk/core": patch
---
Improved middleware pipeline execution speed
---
"@tinyfwk/core": patch
---
Extracted retry logic into separate RetryHandler class for better maintainability
No changeset needed - this is internal refactoring with no user-visible changes
---
"@tinyfwk/api": major
---
Changed CommandBus interface signature
---
"@tinyfwk/api": major
---
Changed command handler registration to require explicit error handling.
Existing handlers must implement error handling or wrap with default handler.
When multiple related changes go together:
---
"@tinyfwk/core": minor
---
- Added support for async middleware execution
- Improved error messages in command validation
- Fixed memory leak in query handler cache
Use bullet points for clarity. Each item should still be user-focused.
For monorepos affecting multiple packages:
---
"@tinyfwk/core": minor
"@tinyfwk/api": minor
---
Added distributed tracing support across all packages
Before finalizing a changeset, verify:
.changeset/ directory exists)feat, fix, or user-impacting refactor/perf.changeset/ directoryWhen creating a commit that needs a changeset:
1. Write code changes
↓
2. Stage files (git add)
↓
3. Create changeset (npx changeset add OR manual file)
↓
4. Stage changeset file (git add .changeset/*)
↓
5. Create commit with conventional commit message
↓
6. Both commit and changeset are included in same commit
Important: The changeset file should be committed alongside the code changes.
❌ "Refactored UserService to use dependency injection" ✅ "Improved application startup time"
❌ "Various improvements and fixes" ✅ "Fixed timeout errors when saving large documents"
❌ "Modified SQL query in UserRepository.findByEmail() to add index hint" ✅ "Improved user search performance"
❌ Creating changeset for test additions ✅ Skip changeset for test-only changes
❌ Marking breaking change as patch
✅ Breaking changes MUST be major
❌ Commit code without changeset file
✅ Always include .changeset/*.md in the commit
A: No. Only commits with user-facing changes need changesets. Typically feat, fix, and some refactor/perf commits.
A: Create one changeset with multiple bullet points, or create two separate changesets. Choose based on clarity for users.
A: Only if the refactoring changes user-visible behavior or performance. Pure internal refactoring = no changeset.
A: Use the changesets CLI (npx changeset add) which generates unique names automatically. Manual naming: use timestamp or random string to avoid conflicts.
A: Yes, but only before the package is released. After release, changesets are consumed into CHANGELOG.md.
A: If documentation change helps users understand a feature better, consider a changeset categorized as "Changed" or "Added". Pure internal docs = no changeset.
Remember:
When in doubt: Ask "Would a user care about this change?" If yes, create changeset. If no, skip it.