Dependency Resolution Settings
overrides
This field allows you to instruct pnpm to override any dependency in the dependency graph, including peer dependencies. This is useful for enforcing all your packages to use a single version of a dependency, backporting a fix, replacing a dependency with a fork, or removing an unused dependency.
Note that the overrides field can only be set at the root of the project.
An example of the overrides field:
overrides:
"foo": "^1.0.0"
"quux": "npm:@myorg/quux@^1.0.0"
"bar@^2.1.0": "3.0.0"
"qar@1>zoo": "2"
You may specify the package the overridden dependency belongs to by
separating the package selector from the dependency selector with a ">", for
example qar@1>zoo will only override the zoo dependency of qar@1, not for
any other dependencies.
To keep an overridden version in sync with the version used elsewhere in your workspace, define the version in a catalog and reference it with the catalog: protocol. This way the version is maintained in a single place and referenced from both your dependencies and your overrides:
catalog:
foo: "^1.0.0"
overrides:
foo: "catalog:"
You may also reference a named catalog with catalog:<name>. See Catalogs for more details.
If you find that your use of a certain package doesn't require one of its dependencies, you may use - to remove it. For example, if package foo@1.0.0 requires a large package named bar for a function that you don't use, removing it could reduce install time:
overrides:
"foo@1.0.0>bar": "-"
This feature is especially useful with optionalDependencies, where most optional packages can be safely skipped.
Convergence overrides
Added in: v11.13.0
A selector with an empty range — "pkg@" — is a convergence override. Unlike a regular override, which rewrites every matching edge unconditionally, a convergence override rewrites a dependency edge only when its version satisfies the range that edge declares:
overrides:
"form-data@": 4.0.6
With the above, a dependency that declares form-data: "^4.0.5" is pinned to 4.0.6, while one that declares ^3.0.0 keeps its own resolution. This lets compatible consumers converge on a single version — now and for any dependent added in the future — without forcing an incompatible version on the rest of the graph.
Rules:
- The value must be an exact version. A range, a dist-tag, or a
-removal fails withERR_PNPM_INVALID_CONVERGENCE_OVERRIDE. Acatalog:reference is allowed as long as the catalog entry resolves to an exact version. - Only plain semver edges participate. Edges declared with
workspace:,catalog:,npm:, a dist-tag, or a git/URL specifier have no meaningful "satisfies" relation and are left untouched. - Convergence overrides cannot be combined with a parent selector:
"parent>pkg@"is rejected. - A regular override always wins over a convergence override for the same edge.
When a full resolution finds that every declared range also admits a newer version, pnpm warns that the override is stale and names the version to converge on instead.
Before v11.13.0, an empty range in an override selector was undocumented and behaved like a bare (unscoped) override.
Overriding peer dependencies
Overrides also apply to peerDependencies. The behavior depends on the type of version specifier used in the override:
- Semver ranges (e.g.,
^1.0.0), workspace, and catalog protocols: the peer dependency is overridden and remains a peer dependency. - Non-range specifiers such as
link:orfile:protocols: the peer dependency is overridden and moved todependencies, since these are not valid peer dependency ranges. - Removal (
-): the peer dependency is removed entirely.
For example, to override the react peer dependency of react-dom:
overrides:
"react-dom>react": "18.1.0"
packageExtensions
The packageExtensions fields offer a way to extend the existing package definitions with additional information. For example, if react-redux should have react-dom in its peerDependencies but it has not, it is possible to patch react-redux using packageExtensions:
packageExtensions:
react-redux:
peerDependencies:
react-dom: "*"
The keys in packageExtensions are package names or package names and semver ranges, so it is possible to patch only some versions of a package:
packageExtensions:
react-redux@1:
peerDependencies:
react-dom: "*"
The following fields may be extended using packageExtensions: dependencies, optionalDependencies, peerDependencies, and peerDependenciesMeta.
A bigger example:
packageExtensions:
express@1:
optionalDependencies:
typescript: "2"
fork-ts-checker-webpack-plugin:
dependencies:
"@babel/core": "1"
peerDependencies:
eslint: ">= 6"
peerDependenciesMeta:
eslint:
optional: true
Together with Yarn, we maintain a database of packageExtensions to patch broken packages in the ecosystem.
If you use packageExtensions, consider sending a PR upstream and contributing your extension to the @yarnpkg/extensions database.
allowedDeprecatedVersions
This setting allows muting deprecation warnings of specific packages.
Exemple:
allowedDeprecatedVersions:
express: "1"
request: "*"
With the above configuration pnpm will not print deprecation warnings about any version of request and about v1 of express.
update
Added in: v11.16.0
Settings in this section tune the pnpm update and pnpm outdated commands.
update.ignoreDeps
Sometimes you can't update a dependency. For instance, the latest version of the dependency started to use ESM but your project is not yet in ESM. Annoyingly, such a package will be always printed out by the pnpm outdated command and updated, when running pnpm update --latest. However, you may list packages that you don't want to upgrade in the ignoreDeps field:
update:
ignoreDeps:
- load-json-file
Patterns are also supported, so you may ignore any packages from a scope: @babel/*.
update.changeset
Added in: v11.16.0
- Default: false
- Type: Boolean
When true, pnpm update writes a change intent after updating workspace manifests, declaring a patch bump for every workspace package whose dependencies or optionalDependencies were changed by the update and a major bump when its peerDependencies changed. Same as passing --changeset; pass --no-changeset to override the setting for a single run.
update.githubActions
Added in: v11.16.0
- Default: false
- Type: Boolean
When true, pnpm update and pnpm outdated also check the GitHub Actions referenced by the repository's workflow files. Same as passing --include-github-actions. See Updating GitHub Actions.
update.githubActionsServer
Added in: v11.17.0
- Default: the
GITHUB_SERVER_URLenvironment variable, falling back to https://github.com - Type: URL
The base URL of the GitHub server that hosts the repositories of the GitHub Actions referenced by the workflow files (for example, a GitHub Enterprise Server). The URL must use the https:// or http:// protocol. Only use http:// for a trusted server on a trusted network: the refs used to pin actions to commit hashes are fetched over this URL, and unencrypted traffic can be tampered with.
Before v11.16.0, update.ignoreDeps was named updateConfig.ignoreDependencies. The deprecated updateConfig setting keeps working until the next major version; when both are set, the update section takes precedence and a warning is printed.
supportedArchitectures
You can specify architectures for which you'd like to install optional dependencies, even if they don't match the architecture of the system running the install.
For example, the following configuration tells to install optional dependencies for Windows x64:
supportedArchitectures:
os:
- win32
cpu:
- x64
Whereas this configuration will install optional dependencies for Windows, macOS, and the architecture of the system currently running the install. It includes artifacts for both x64 and arm64 CPUs:
supportedArchitectures:
os:
- win32
- darwin
- current
cpu:
- x64
- arm64
Additionally, supportedArchitectures also supports specifying the libc of the system.
ignoredOptionalDependencies
If an optional dependency has its name included in this array, it will be skipped. For example:
ignoredOptionalDependencies:
- fsevents
- "@esbuild/*"
minimumReleaseAge
Added in: v10.16.0
- Default: 1440 (since v11), 0 (before v11)
- Type: number (minutes)
To reduce the risk of installing compromised packages, you can delay the installation of newly published versions. In most cases, malicious releases are discovered and removed from the registry within an hour.
minimumReleaseAge defines the minimum number of minutes that must pass after a version is published before pnpm will install it. This applies to all dependencies, including transitive ones.
For example, the following setting ensures that only packages released at least one day ago can be installed:
minimumReleaseAge: 1440
minimumReleaseAgeExclude
Added in: v10.16.0
- Default: undefined
- Type: string[]
If you set minimumReleaseAge but need certain dependencies to always install the newest version immediately, you can list them under minimumReleaseAgeExclude. The exclusion works by package name and applies to all versions of that package.
Exemple:
minimumReleaseAge: 1440
minimumReleaseAgeExclude:
- webpack
- react
In this case, all dependencies must be at least a day old, except webpack and react, which are installed immediately upon release.
Added in: v10.17.0
You may also use patterns. For instance, allow all packages from your org:
minimumReleaseAge: 1440
minimumReleaseAgeExclude:
- '@myorg/*'
Added in: v10.19.0
You may also exempt specific versions (or a list of specific versions using a disjunction with ||). This allows pinning exceptions to mature-time rules:
minimumReleaseAge: 1440
minimumReleaseAgeExclude:
- nx@21.6.5
- webpack@4.47.0 || 5.102.1
minimumReleaseAgeIgnoreMissingTime
Added in: v11.0.0
- Default: true
- Type: Boolean
When true, pnpm skips the minimumReleaseAge check for a package whose registry metadata does not include the time field (some private registries and mirrors omit it). Set to false to fail resolution in that case instead of installing the package.
minimumReleaseAgeIgnoreMissingTime: false
minimumReleaseAgeStrict
Added in: v11.0.0
- Default: true if
minimumReleaseAgeis explicitly configured, false otherwise - Type: Boolean
Controls how pnpm behaves when no version of a dependency satisfies the minimumReleaseAge constraint within the requested range. When false, pnpm falls back to a version that doesn't meet the minimumReleaseAge constraint so installation can still succeed. When true, pnpm fails resolution instead.
The default depends on whether you configured minimumReleaseAge yourself: if you set it explicitly (via pnpm-workspace.yaml, the CLI, or environment variables), strict mode is on by default so the setting is enforced. The built-in default of minimumReleaseAge (1440 minutes) is non-strict for backward compatibility.
minimumReleaseAgeStrict: true
trustPolicy
Added in: v10.21.0
- Default: off
- Type: no-downgrade | off
When set to no-downgrade, pnpm will fail if a package's trust level has decreased compared to previous releases. For example, if a package was previously published by a trusted publisher but now only has provenance or no trust evidence, installation will fail. This helps prevent installing potentially compromised versions. Trust checks are based solely on publish date, not semver. A package cannot be installed if any earlier-published version had stronger trust evidence. Starting in v10.24.0, prerelease versions are ignored when evaluating trust evidence for a non-prerelease install, so a trusted prerelease cannot block a stable release that lacks trust evidence.
trustPolicyExclude
Added in: v10.22.0
- Default: []
- Type: string[]
A list of package selectors that should be excluded from the trust policy check. This allows you to install specific packages or versions even if they don't satisfy the trustPolicy requirement.
For example:
trustPolicy: no-downgrade
trustPolicyExclude:
- 'chokidar@4.0.3'
- 'webpack@4.47.0 || 5.102.1'
- '@babel/core@7.28.5'
trustPolicyIgnoreAfter
Added in: v10.27.0
- Default: undefined
- Type: number (minutes)
Allows ignoring the trust policy check for packages published more than the specified number of minutes ago. This is useful when enabling strict trust policies, as it allows older versions of packages (which may lack a process for publishing with signatures or provenance) to be installed without manual exclusion, assuming they are safe due to their age.
trustLockfile
Added in: v11.3.0
- Default: false
- Type: Boolean
When true, pnpm install skips the supply-chain verification pass that re-applies minimumReleaseAge and trustPolicy to every entry in the loaded lockfile. The install treats the lockfile as already trusted.
Useful in environments where the lockfile is effectively part of the trusted base — closed-source projects where every commit comes from a trusted author. A poisoned lockfile (one a contributor authored under a weaker policy than CI enforces) can slip through, so leave this false whenever outside collaborators can edit the lockfile.
On large workspaces the verification pass holds per-package registry metadata in memory for the duration of the install; disabling it cuts memory usage at the cost of the supply-chain check. Most projects with the default frozenLockfile CI workflow do not need to set this.
blockExoticSubdeps
Added in: v10.26.0
- Default: true
- Type: Boolean
When set to true, only direct dependencies (those listed in your root package.json) may use exotic sources (like git repositories or direct tarball URLs). All transitive dependencies must be resolved from a trusted source, such as the configured registry, local file paths, workspace links, or trusted GitHub repositories (node, bun, deno).
This setting helps secure the dependency supply chain by preventing transitive dependencies from pulling in code from untrusted locations.
Exotic sources include:
- Git repositories (
git+ssh://...) - Direct URL links to tarballs (
https://.../package.tgz)
registries
Added in: v11.0.0
- Default: undefined
- Type: Record<string, string>
Configure registries for scoped packages in pnpm-workspace.yaml. The default key sets the main registry (equivalent to the registry .npmrc setting). Scoped keys configure registries for specific package scopes.
registries:
default: https://registry.npmjs.org/
"@my-org": https://private.example.com/
"@internal": https://nexus.corp.com/
Since v11.11.0, this setting may also be defined in the global configuration file (config.yaml), which is useful for registries that should apply to every project on the machine rather than to a single repository.
namedRegistries
Added in: v11.1.0
- Default: undefined
- Type: Record<string, string>
Defines named registry aliases that can be used as a prefix when installing packages, in the style of vlt's named-registry aliases. For example, with the following configuration:
namedRegistries:
gh: https://npm.pkg.github.example.com/
work: https://npm.work.example.com/
pnpm add work:@corp/lib@^2.0.0 resolves @corp/lib@^2.0.0 against https://npm.work.example.com/.
The gh: alias is built in and points at the GitHub Packages npm registry (https://npm.pkg.github.com/) by default. Override it under namedRegistries for GitHub Enterprise Server.
Authentication is picked up from the existing per-URL .npmrc entries (e.g. //npm.pkg.github.com/:_authToken=...), so no separate auth mechanism is required.
Since v11.11.0, this setting may also be defined in the global configuration file (config.yaml), so an alias like work: can be shared across every project on the machine.