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.
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.
Both the parent selector and the target selector support * wildcard patterns on package names:
overrides:
"@esbuild/*:optional": "-"
"@mui/*>react:peer": "^17.0.0 || ^18.0.0"
Dependency-type selectors#
By default, an override applies to dependencies, devDependencies, optionalDependencies, and peerDependencies. Append a Dependency Selector Syntax pseudo-selector to the target to restrict the override to one dependency group:
:prodmatches onlydependencies.:optionalmatches onlyoptionalDependencies.:peermatches onlypeerDependencies.
overrides:
"foo:prod": "^2.0.0"
"@esbuild/*:optional": "-"
"react-dom>react:peer": "^18.0.0 || ^19.0.0"
When an override removes an entry from optionalDependencies with "-", pnpm also removes any duplicate declaration of that package from dependencies in the same manifest.
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#
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.
Overriding peer dependencies#
Overrides also apply to peerDependencies. Use :peer on the target selector to target only peerDependencies without overriding direct or transitive runtime dependencies of the same name:
- Version ranges (e.g.,
^1.0.0,*), workspace, and catalog protocols: the peer dependency range is replaced inpeerDependencies. - Non-range specifiers such as
link:,file:, ornpm:protocols:peerDependenciesis left unchanged (so an untyped override like"foo": "file:./foo.tgz"replacesfooindependencieswithout wiping out consumers' peer version ranges). - Removal (
-): the peer dependency (and itspeerDependenciesMetaentry) is removed.
For example, to widen the react peer dependency of react-dom, or to allow any version for @babel/* peer dependencies:
overrides:
"react-dom>react:peer": "^18.0.0 || ^19.0.0"
"@babel/*:peer": "*"
To replace a package's peer dependency with a direct dependency, add the dependency in packageExtensions and remove the peer declaration with :peer:
packageExtensions:
react-dom:
dependencies:
react: "18.3.1"
overrides:
"react-dom>react:peer": "-"
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
Tip
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.
Example:
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#
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 always be 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#
- 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#
- 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#
- 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.
Info
updateConfig.ignoreDependencies is the deprecated name of update.ignoreDeps and keeps working. 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.
Note
Copying node_modules between platforms can cause native-module load errors,
such as invalid ELF header or not a valid Win32 application. For packages
that publish platform-specific optional dependencies, list the target operating
systems, CPUs, and C libraries in supportedArchitectures before installing.
The lockfile can contain separate entries for each platform variant.
This setting does not cross-compile native addons. If a package builds its addon in an install script, install or rebuild it on the target platform.
Platform lists#
Added in: v12.5.0
Instead of the os, cpu, and libc mapping, list the exact platforms to prepare:
supportedArchitectures:
- linux-x64
- linux-x64-musl
- darwin-arm64
- win32-x64
Each entry is <os>-<cpu>, optionally followed by a Linux C library, such as linux-x64-manylinux_2_28. Linux entries without a C library mean glibc. Rust target triples are accepted too: x86_64-unknown-linux-gnu is equivalent to linux-x64. current includes the platform running the install.
The list prepares only the named platforms. The mapping form continues to work with its existing meaning. Python uses these targets together with python.versions when locking for multiple environments.
optional#
- Default: true
- Type: Boolean
Set to false to skip optional dependencies during installation, including
transitive optional dependencies. Equivalent to
pnpm install --no-optional.
ignoredOptionalDependencies#
Note
Deprecated: use overrides with :optional and "-" instead (for example, "fsevents:optional": "-" and "@esbuild/*:optional": "-"). ignoredOptionalDependencies continues to work for backward compatibility.
If an optional dependency has its name included in this array, it will be skipped. For example:
ignoredOptionalDependencies:
- fsevents
- "@esbuild/*"
forceIgnoresPlatform#
Added in: v12.7.0
- Default: false
- Type: Boolean
When true, pnpm install --force also installs
optional dependencies whose os, cpu, or libc do not match the host. When
false, --force refetches every package but still skips optional dependencies
built for other platforms.
pnpm v11 behaved as if this setting were true. To install optional
dependencies for other platforms on purpose, prefer
supportedArchitectures.
minimumReleaseAge#
- Default: 1440
- Type: number (minutes)
To reduce the risk of installing compromised or defective 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. It does not apply to a config dependency pinned with version+integrity.
For example, the following setting ensures that only packages released at least one day ago can be installed:
minimumReleaseAge: 1440
minimumReleaseAgeExclude#
- 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.
Example:
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.
You may also use patterns. For instance, allow all packages from your org:
minimumReleaseAge: 1440
minimumReleaseAgeExclude:
- '@myorg/*'
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
minimumReleaseAgeExcludePrune#
- Default: false
- Type: Boolean
When set to true, pnpm install, pnpm add, pnpm update, pnpm remove, and pnpm dedupe prune the entries of minimumReleaseAgeExclude in pnpm-workspace.yaml that the freshly written lockfile no longer resolves: a version that is gone is dropped (an entry is removed once none of its versions remain), and an entry for a package that is no longer in the lockfile is removed too. Name patterns (@myorg/*) are always kept. Pruning also checks resolved configuration dependencies and their transitive dependencies.
The cleanup is skipped when the install's lockfile does not cover the whole workspace (sharedWorkspaceLockfile: false), since entries another project still needs would look stale. Comments on the entries that are kept survive the rewrite.
minimumReleaseAgeIgnoreMissingTime#
- 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
The setting also governs trustPolicy, which reads the same publish dates: trustPolicy: no-downgrade skips a package the registry cannot date, with a warning, rather than failing the install with ERR_PNPM_MISSING_TIME.
The opt-in covers a registry that cannot date its releases, not a package a registry says it never published: during lockfile verification, a lockfile entry missing from a packument that does date every version it lists remains a hard failure.
minimumReleaseAgeStrict#
- 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 (in pnpm-workspace.yaml, in the global config.yaml, through a PNPM_CONFIG_* variable, or on the command line), 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#
- 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. 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.
The check also covers the pnpm version a project pins in packageManager or devEngines.packageManager. pnpm fails before it switches to that version or records it in the lockfile.
trustPolicyExclude#
- 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#
- 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.
trustPolicyExcludePrune#
Added in: v12.4.0
- Default: false
- Type: Boolean
When set to true, pnpm install, pnpm add, pnpm update, pnpm remove, and pnpm dedupe prune the entries of trustPolicyExclude in pnpm-workspace.yaml that the freshly written lockfile no longer resolves: a version that is gone is dropped (an entry is removed once none of its versions remain), and an entry for a package that is no longer in the lockfile is removed too. Name patterns (@myorg/*) are always kept. Pruning also checks resolved configuration dependencies and their transitive dependencies.
The cleanup is skipped when the install's lockfile does not cover the whole workspace (sharedWorkspaceLockfile: false), since entries another project still needs would look stale. Comments on the entries that are kept survive the rewrite.
trustLockfile#
- 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#
- 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#
- Default: undefined
- Type: Record<string, RegistryDeclaration> or Record<string, string>
Declares the registries the project installs from. Each registry is declared once, keyed by its URL, with everything pnpm knows about it in the entry: the scopes routed to it, the bare-specifier prefix it answers to, how the server lays out tarball URLs (serverType, supportsTimeField), and how many requests pnpm keeps in flight to it (networkConcurrency). The full description of each field is on the dedicated Registries page.
registries:
https://npm.corp.example.com/:
serverType: artifactory
scopes: ["@my-org", "@internal"]
prefix: work
The older shape, mapping scopes to URLs, is still accepted. The default key sets the main registry (equivalent to the registry .npmrc setting), and 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/
The two shapes cannot be mixed in one map.
pnpm normalizes https://registry.npmjs.com/ to https://registry.npmjs.org/. Credentials configured for either hostname at the registry root apply to the canonical registry. HTTP URLs, custom ports, and registry subpaths are unchanged.
For URL-scoped environment credentials, an explicit registry.npmjs.org entry takes precedence over a registry.npmjs.com entry.
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. Ecosystem indexes, routes (scopes and prefix), and networkConcurrency are read from there; serverType and supportsTimeField shape the lockfile, so they are read only from pnpm-workspace.yaml. See where the setting may live.
namedRegistries#
- Default: undefined
- Type: Record<string, string>
Note
Deprecated: declare a prefix in registries instead. See the Registries page. namedRegistries is still read, but only for prefixes that registries does not declare; when both settings declare prefixes, pnpm warns. Everything below about aliases (the built-in ones, reserved names, and the lockfile keys) applies to prefix-declared aliases the same way.
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/.
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.
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.
Built-in aliases#
Two aliases work without any configuration:
| Alias | Registry | Notes |
|---|---|---|
gh: | https://npm.pkg.github.com/ | The GitHub Packages npm registry. |
npmjs: | https://registry.npmjs.org/ | The public npm registry. |
Entries you define under namedRegistries are merged on top of these, so either one can be overridden. GitHub Enterprise Server users point gh at their own host, and an organization that mirrors or proxies npmjs should point npmjs at the mirror:
namedRegistries:
gh: https://npm.pkg.github.example.com/
npmjs: https://npm.internal.example.com/
npmjs: pins a dependency to the public registry even when the default registry points somewhere else, such as an internal proxy:
{
"dependencies": {
"left-pad": "npmjs:^1.3.0"
}
}
The npm: prefix cannot do this. It is the alias protocol (npm:<name>@<range>) and resolves through whatever registry points at.
The built-in URLs are also the prefixes that a tarball URL recorded in the lockfile is matched against when pnpm verifies a package. If you proxy npmjs and do not override the alias, an entry whose tarball URL is on registry.npmjs.org is verified against the public registry rather than against your mirror. This only affects lockfiles that record such a URL (a canonical URL for your configured registry is omitted from the lockfile), and only when a tarball-URL, minimumReleaseAge, or trustPolicy check runs.
Reserved alias names#
An alias that shadows a reserved dependency specifier prefix (file, link, workspace, runtime, npm, jsr, git, github, gitlab, bitbucket, catalog, custom, http, https, ssh) is rejected with ERR_PNPM_RESERVED_NAMED_REGISTRY_NAME. Since v12.5.0, pkg is also reserved, regardless of case, for Package URLs. Since v12.13.0, tool is reserved for provisioned tools. An alias must also start with a letter and contain only letters, digits, ., _, and -.
Named registries in the lockfile#
A package resolved from a named registry is recorded in pnpm-lock.yaml under a registry-qualified key, <name>@<registryName>:<version>:
packages:
foo@work:1.0.0:
resolution: {integrity: sha512-...}
Keyed by name@version alone, the same name and version served by two registries would collapse onto a single entry, and whichever resolved first would decide the tarball that every consumer got. That is a package-substitution risk: a package you expect from your private registry could be installed from another registry that publishes the same name and version, with nothing in the lockfile to reveal it. Registry-qualified keys give each registry its own entry and pin which one a dependency came from.
The lockfile format version is unchanged, and qualified keys appear only for packages resolved from a named registry, including the built-in gh: and npmjs: aliases, which need no namedRegistries entry. A project that declares no prefix and installs nothing through an alias sees no difference, and older pnpm versions keep reading the file.
The key names the registry a package resolved from, not the way its dependency was written. A registry that declares a prefix, through prefix in registries or through namedRegistries, keys every package resolved from it with that prefix: one written as work:^1.0.0, one written as a plain range whose scope registries routes to that URL, and one the default registry serves when the prefix points at it. A plain range and a prefixed specifier that reach one registry therefore share one packages: entry and one copy in node_modules/.pnpm, so a published package that depends on @work/util by a plain range shares the copy your project installs through work:. The built-in gh: and npmjs: aliases qualify only the specifiers that spell them: routing a scope to registry.npmjs.org does not turn its keys into npmjs: keys unless you declare that prefix yourself. The same name and version served by two registries still get two entries.
When several prefixes declare one registry, its packages are keyed by the lexicographically smallest prefix, so work:^1.0.0 and zeta:^1.0.0 pointing at one URL record foo@work:1.0.0. The specifier in package.json is left as written.
Caution
If any dependency is installed through an alias, your first non-frozen install on v11.20.0 or newer re-keys those entries, which shows up as a lockfile diff. Commit it. That diff is the fix being applied. Review it too: an entry that moves to a registry you did not expect is worth investigating.
The same applies when a scope you route reaches a registry that also declares a prefix: the next pnpm install moves the scope-routed entries under the prefix and merges them with the prefixed ones. A frozen install keeps installing the lockfile as recorded.
Have everyone working on the project move to v11.20.0 or newer first. An older pnpm reads the re-keyed lockfile fine, and frozen installs are unaffected, but it does not produce registry-qualified keys itself: any install that updates the lockfile writes those entries back to the old shape, and the next install on a current pnpm re-qualifies them. The lockfile then flips back and forth, and while it is in the old shape the project is exposed again. Because the lockfile format version is deliberately unchanged, pnpm cannot detect this and warn you.
There is no setting to keep the old behavior. The old shape is the vulnerability.
A plain key records no registry, so pnpm remembers in the workspace state (node_modules/.pnpm-workspace-state-v1.json) which registry each scope routed to when it last resolved the lockfile. When you route a scope to another registry, the next pnpm install resolves that scope's packages and their dependencies again from the new registry, at the locked versions it serves, and picks another version in range for a locked version it does not serve. A frozen install keeps installing the lockfile as recorded. Without that record, as in a fresh clone, pnpm reads the plain keys as resolved from the registries configured now. Only scope routes are tracked this way: changing the default registry, which is routinely a switch between mirrors, does not resolve anything again.
Every non-built-in alias that the lockfile references must stay declared, through prefix in registries or through namedRegistries. Reading an entry whose alias is gone fails with ERR_PNPM_MISSING_NAMED_REGISTRY rather than falling back to the default registry, since that would fetch a different package. Renaming an alias re-resolves the packages that used it.
Tarball URLs that follow the standard registry layout are not written to the lockfile for named-registry packages; they are recomputed from the alias's declared URL on demand.
pnprServer#
- Default: null
- Type: String
URL of a pnpr server. See Install acceleration.
When set, pnpm install offloads dependency resolution to the remote pnpr server. pnpm sends its workspace manifests and registry configuration to the server, and the server resolves the dependency graph against those registries, streaming back resolved package metadata frames as it walks the graph so pnpm can download tarballs in parallel. Once resolution finishes, the server returns the complete lockfile and pnpm links node_modules locally.
Public packages are fetched directly from their respective registries in parallel. Private packages configured through pnpr are fetched from its registry endpoint using server-side upstream credentials; client upstream registry credentials are not sent to the pnpr server.
pnprServer: https://pnpr.example.com/
This can also be configured via the --config.pnprServer=<url> command-line option or the PNPM_CONFIG_PNPR_SERVER environment variable.
When pnprServer is set, authentication headers configured for the pnpr server URL in .npmrc (for example, //pnpr.example.com/:_authToken=...) are automatically sent to authenticate requests to the server.
autoDedupe#
Added in: v12.6.0
- Default: false
- Type: Boolean
When set to true, pnpm install and pnpm add deduplicate compatible dependency versions during installation. If a dependency appears at multiple versions and one version satisfies every range in the workspace, pnpm picks that version for all of them.
When set to false, each project's dependencies resolve from its own ranges. For example, a project with ajv: "*" gets the latest Ajv even if another project depends on ajv@^6. Packages that a project lists in peerDependencies still follow the versions other projects use. Run pnpm dedupe to make both projects use one version. Set autoDedupe: true if you check the lockfile with pnpm dedupe --check.
Deduplication covers the whole workspace. A filtered command such as pnpm --filter <project> add can also change the lockfile entries of projects outside the filter. Those projects get the deduplicated versions linked on the next pnpm install.
autoDedupe: true
Frozen installs (--frozen-lockfile) leave the lockfile unchanged. Deduplication only runs when the lockfile is being written.
To let installs on other machines reuse a deduplicated lockfile, set lockfile.includeResolutionSettings.
pnpm install --lockfile-only skips resolution when nothing changed since a deduplicating pnpm install --lockfile-only wrote the lockfile. Such an install keeps the lockfile even if versions were published since then, or if only a setting such as resolutionMode changed. Run pnpm dedupe to apply such a change.