Files
bun-src/docs/pm/overrides.mdx
2026-08-27 21:09:14 +00:00

154 lines
4.7 KiB
Plaintext

---
title: "Overrides and resolutions"
description: "Control metadependency versions with npm overrides and Yarn resolutions"
---
Bun supports npm's `"overrides"` and Yarn's `"resolutions"` in `package.json`. Both specify a version range for _metadependencies_, the dependencies of your dependencies.
{/* prettier-ignore */}
```json package.json icon="file-json"
{
"name": "my-app",
"dependencies": {
"foo": "^2.0.0"
},
"overrides": { // [!code ++]
"bar": "~4.4.0" // [!code ++]
} // [!code ++]
}
```
By default, Bun installs the latest version of all dependencies and metadependencies, according to the ranges specified in each package's `package.json`. Say your project has one dependency, `foo`, which in turn depends on `bar`. That makes `bar` a _metadependency_ of your project.
```json package.json icon="file-json"
{
"name": "my-app",
"dependencies": {
"foo": "^2.0.0"
}
}
```
When you run `bun install`, Bun installs the latest version of each package.
```txt tree layout of node_modules icon="list-tree"
node_modules
├── [email protected]
└── [email protected]
```
If a security vulnerability is introduced in `[email protected]`, you may want to pin `bar` to an older version that doesn't have it. That's what `"overrides"` and `"resolutions"` are for.
---
## `"overrides"`
Add `bar` to the `"overrides"` field in `package.json`. Bun defers to the specified version range when determining which version of `bar` to install, whether it's a dependency or a metadependency.
{/* prettier-ignore */}
```json package.json icon="file-json"
{
"name": "my-app",
"dependencies": {
"foo": "^2.0.0"
},
"overrides": { // [!code ++]
"bar": "~4.4.0" // [!code ++]
} // [!code ++]
}
```
Bun only reads overrides from the root `package.json`, not from workspace packages. Overrides apply to `peerDependencies` as well.
## `"resolutions"`
`"resolutions"` is Yarn's alternative to `"overrides"`, with similar syntax. Bun supports it to help projects migrate from Yarn.
{/* prettier-ignore */}
```json package.json icon="file-json"
{
"name": "my-app",
"dependencies": {
"foo": "^2.0.0"
},
"resolutions": { // [!code ++]
"bar": "~4.4.0" // [!code ++]
} // [!code ++]
}
```
## Values
A value can be any dependency specifier, not only a version range. `npm:` swaps a package for a fork, and `catalog:` (or `catalog:<name>`) keeps the overridden version in sync with a [workspace catalog](/pm/catalogs):
```json package.json icon="file-json"
{
"name": "my-app",
"overrides": {
"quux": "npm:@myorg/quux@^1.0.0",
"foo": "catalog:"
}
}
```
A value of `"$name"` reuses the range you declared for `name` in your own dependencies, so `"bar": "$foo"` pins `bar` to whatever range you declared for `foo`.
## Nested overrides
You can scope a rule to one parent package, so it only applies to that package's direct dependency. Bun accepts the npm object form, the pnpm `>` form, and a parent with a version range:
```json package.json icon="file-json"
{
"name": "my-app",
"overrides": {
"micromatch": {
".": "^4.0.5",
"picomatch": "^2.3.2"
},
"micromatch>picomatch": "^2.3.2",
"micromatch@^4>picomatch": "^2.3.2"
}
}
```
`"."` inside an object overrides `micromatch` itself, like a top-level `"micromatch"` rule.
`"resolutions"` accepts Yarn's path form. Bun accepts `**` for compatibility, but either way the rule only affects the parent's direct dependency:
```json package.json icon="file-json"
{
"name": "my-app",
"resolutions": {
"micromatch/picomatch": "^2.3.2",
"**/micromatch/**/picomatch": "^2.3.2"
}
}
```
When several rules match, the most specific wins: parent-with-version > parent > top-level.
## Version-scoped overrides
The key can carry a version selector so the rule only applies to dependents whose declared range overlaps it. This is the form `pnpm audit --fix` writes:
```json package.json icon="file-json"
{
"name": "my-app",
"overrides": {
"semver@<7.5.2": "7.5.2",
"webpack>terser@4": "4.8.1",
"terser@4": {
".": "4.8.1"
}
}
}
```
Bun compares the selector with the range each dependent _declares_, not the resolved version. `"semver@<7.5.2"` applies to a dependent that declares `^7.3.0` (which could still pick `7.3.x`) but not to one that declares `^7.5.2`. Dependents using a dist-tag, `catalog:`, `workspace:`, git, or URL specifier never match a selector.
## Limitations
- Bun supports only one parent level. It ignores `a>b>c`, `a/b/c`, and deeper object nesting with a warning.
- Bun does not support pnpm's `"pkg@"` (empty selector) and `"-"` (remove dependency) forms, and skips them with a warning.
- Bun writes a lockfile containing nested or version-scoped rules as `lockfileVersion` 3, which older versions of Bun cannot read.