-
Notifications
You must be signed in to change notification settings - Fork 745
Description
Allow configuring which packages'
devDependencieschanges should trigger version bumps for their dependents.
Motivation
By design, Changesets does not treat devDependencies as part of release semantics. Only when internal runtime dependencies (such as dependencies, peerDependencies, etc.) have version changes will dependent packages be bumped accordingly.
This default behavior is correct and necessary in most scenarios, because: devDependencies typically only affect development, build, and testing processes, not the final artifacts delivered to users.
However, in modern monorepos, there exists a special class of packages that publish "bundled/pre-compiled artifacts" as their release output. In these packages, the above assumption does not hold. Their characteristics include:
- Publishing bundled JavaScript/CSS instead of source code
- Build steps are a core part of the release process
For these packages, build-time dependencies are already bundled into the final artifacts, and users don't need these dependencies at runtime. Therefore, declaring them in devDependencies is the correct approach—this prevents users from redundantly installing already-bundled code, reducing dependency tree size.
However, this also introduces a versioning semantic problem: when build-time dependencies in devDependencies change, the final published artifact has already changed, but the package version number remains unchanged. This leads to:
- Same version number corresponding to different artifacts — breaking version semantics
- Non-reproducible release results — difficult to rollback
- Difficult debugging for users — unable to trace changes through versions
Proposed Solution
Add an bumpOnDevDependencies field in .changeset/config.json to explicitly declare which packages' devDependencies changes have release semantics.
Configuration Example
{
"bumpOnDevDependencies": ["@example/runtime", "@example/design-system"]
}Semantics
- When packages in the array are modified, all packages depending on them via
devDependenciesshould publish new versions - When packages outside the array are modified, packages depending on them via
devDependenciesdo not need to publish new versions - Does not affect
dependencies/peerDependenciesrelationships (handled by existing Changesets mechanism)
Behavior Comparison
After configuration:
@example/runtime (in configuration) is modified
↑ devDependencies
@example/app → publish new version ✅
eslint-config (not in configuration) is modified
↑ devDependencies
@example/app → do not publish new version ❌
Design Principles
Explicit declaration, opt-in mode
- Default behavior:
devDependencieschanges do not trigger version updates (fits most scenarios) - Only explicitly configured packages have devDeps release semantics
- Rationale: bundled packages are a minority in monorepos
Support glob patterns
- Consistent with existing configurations like
ignore - Convenient for batch configuration (e.g.,
@example/*-runtime)
Alternative Solutions Considered
Option A: Declaration in package.json
Add a field in each package's package.json to explicitly express that the current package has bundled dependencies:
{
"name": "@example/runtime",
"changeset": {
"bumpOnDevDependencies": true
}
}Or specify concrete dependencies:
{
"name": "@example/runtime",
"changeset": {
"bumpOnDevDependencies": ["@example/compiler", "@example/optimizer"]
}
}Pros:
- ✅ Configuration stays with the package itself, better aligns with "bundled package" being an inherent property
- ✅ Package maintainers clearly declare their release semantics
- ✅ Supports finer-grained configuration (specify which devDeps are bundled)
Cons:
- ❌ Lacks global perspective, difficult to quickly understand which packages in the entire monorepo are bundled
- ❌ Inconsistent with Changesets design pattern: all configurations are centralized in
.changeset/config.json, no precedent forpackage.jsondeclarations