Overrides
overrides in package.json forces a specific version of a dependency — including transitive dependencies that your code does not declare directly. Typical uses:
- Patching a CVE in a deep dependency you do not control
- Pinning a breaking transitive update until upstream catches up
- Deduplicating when the tree picks multiple versions of the same library
- Applying different versions per workspace in a monorepo
utoo supports the full npm overrides syntax, plus yarn’s equivalent resolutions field.
Overrides are read only from the root package.json. utoo does not honor overrides declared inside a published dependency.
Catalog vs. overrides — which one?
Both pin versions, but solve different problems:
- Catalog — your own workspaces opt in via
"react": "catalog:". Affects only packages that reference the catalog. - Overrides — forces a version on every resolution (including deep transitive deps), even in third-party packages.
Use a catalog for internal version consistency; use overrides to fix something in the tree you don’t directly own.
Simple override
Force every copy of lodash in the tree to 4.17.21:
{
"overrides": {
"lodash": "4.17.21"
}
}The value can be any package spec — exact version, semver range, npm: alias, git URL, etc.
Conditional override
Only override when the existing range matches. Useful when you want the fix to apply only to a specific legacy range:
{
"overrides": {
"lodash@^3.0.0": "4.17.21"
}
}Any lodash@^3.0.0 in the tree is replaced with 4.17.21; lodash@^4.17.0 is left alone.
Reference the root version
Use $<name> to sync an override with your own top-level dependencies / devDependencies — one edit keeps both aligned:
{
"dependencies": {
"react": "^18.2.0"
},
"overrides": {
"react": "$react"
}
}Bumping react in dependencies automatically bumps every transitive copy.
Nested override
Scope an override to a specific parent. debug only gets replaced when it is pulled in by express:
{
"overrides": {
"express": {
"debug": "4.0.0"
}
}
}Nesting can go arbitrarily deep. Replace debug only when express → body-parser → debug:
{
"overrides": {
"express": {
"body-parser": {
"debug": "3.0.0"
}
}
}
}Override the parent itself (".")
Inside a nested override, the key "." means “replace the parent package, not a child.” Combined with a version range on the outer key, this pins express@^4.0.0 to 4.18.0:
{
"overrides": {
"express@^4.0.0": {
".": "4.18.0"
}
}
}Per-workspace override
In a monorepo, nest under a workspace package name to scope an override to one workspace:
{
"workspaces": ["packages/*"],
"overrides": {
"workspace-a": {
"lodash": "3.0.0"
},
"workspace-b": {
"lodash": "4.0.0"
}
}
}lodash inside packages/workspace-a resolves to 3.0.0; inside packages/workspace-b to 4.0.0.
Yarn resolutions compatibility
For projects migrating from yarn, the resolutions field is parsed alongside overrides:
{
"overrides": {
"lodash": "4.17.21"
},
"resolutions": {
"debug": "4.0.0"
}
}Both apply. If the same key appears in both, overrides wins.
Related
- Package Specs — all value forms accepted on the right side of an override.
- Catalog — opt-in shared versions for your own workspaces.
- Migrating from pnpm —
ut install --from pnpmcarriesoverridesover frompnpm-workspace.yaml.