154 lines
4.7 KiB
Plaintext
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.
|