NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #3648 most downloaded on npm
Basic types used by pnpm
Last release 10 days ago
25 Sep 2026
Release timing varies
gaps range from 8 days to 3 months
Most releases are documented
notes for 51 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
9 years old
99 releases · first in 2017
A dependency that ships a binding.gyp and sets gypfile: false no longer gets the node-gyp rebuild install script pnpm synthesizes for it. Such a depen
A dependency that ships a binding.gyp and sets gypfile: false no longer gets the node-gyp rebuild install script pnpm synthesizes for it. Such a dependency needs no allowBuilds entry and is no longer listed under "Ignored build scripts".
Added a --peer flag to pnpm update to update ranges in peerDependencies #8081.
Added an opt-in proof of concept that lets installs reuse a dependency's build output across machines, by publishing and restoring signed, organizatio
Added an opt-in proof of concept that lets installs reuse a dependency's build output across machines, by publishing and restoring signed, organization-scoped artifacts through pnpr instead of running the lifecycle scripts locally.
Configure it with the new remoteSideEffectsCache setting. A workspace names the eligible organization and packages; everything describing the act of signing — publish, keyId, builderId, trustedKeys, privateKey and the provenance fields — is refused in pnpm-workspace.yaml and read from the global config file or the environment instead.
Added the audit.ignorePrune setting. When set to true, pnpm audit --fix removes ignored GHSA entries that no longer appear in the audit report.
Added per-task concurrency limits to workspace task orchestration. Set tasks.<name>.concurrency in pnpm-workspace.yaml to limit how many instances of that task may run across workspace projects at once:
tasks:
build:
concurrency: 2
sideEffectsCache now declares the whole of how a package's build output is reused — whether one is restored, whether one is saved, and the remote tier that shares it between machines:
sideEffectsCache:
read: true
write: true
remote:
org: acme
packages: ['native-addon']
sideEffectsCache: true, sideEffectsCacheReadonly, remoteSideEffectsCache, and its organization field all keep working. Where a field is set under both spellings the one above wins; where it is set under only one, it is kept.
Two behaviors change, both bringing this CLI in line with what the Rust one already did: sideEffectsCacheReadonly: true now blocks writing to the cache, and setting it alongside sideEffectsCache: false gives a read-only view rather than switching the cache off entirely. A cache can also be declared write-only now, to populate one the run does not read.
Workspace task orchestration (pnpm/rfcs#23). pnpm -r run and pnpm -r exec now schedule per task instead of in topological chunks: a task starts as soon as the tasks it depends on have finished, so a project no longer waits for unrelated projects that happen to share its chunk.
A new tasks section in pnpm-workspace.yaml declares what a task depends on, using the ^ convention:
tasks:
build:
dependsOn: ['^build']
test:
dependsOn: ['build']
lint: {}
^name means the named task in each of the project's workspace dependencies; a bare name means the task in the same project; an entry with no dependsOn declares an empty dependency list. A task with no entry behaves as dependsOn: ['^<its own name>'], which is exactly what the previous chunked ordering implied — an unconfigured workspace gets the scheduler improvement and nothing else changes meaning. A project without the script is reported skipped and passes its edges through to its own dependencies, so a scriptless package does not sever a chain.
Also part of this change:
ERR_PNPM_TASK_CYCLE) instead of silently running in an arbitrary order. Setting ignoreWorkspaceCycles: true downgrades the error to a warning: the cycle's tasks run in an arbitrary order relative to each other.--resume-from now skips exactly the transitive dependencies of the anchor package; work unrelated to the anchor still runs.--no-bail, tasks whose dependencies failed are reported as skipped, not failed, and do not add to the exit code.--bail (the default), the first failure still ends the run at once and nothing new is dispatched — including scripts already queued behind the concurrency limit.pnpm -r run --dry-run <script> prints the task graph that would execute without running anything (including skipping the verifyDepsBeforeRun check); --json emits the tasks and their resolved dependency edges.--workspace-concurrency=1, or the graph forces the scripts to run one after another).One column per quarter.
namedRegistries is deprecated in favor of the prefix field, and is still read for prefixes registries does not declare.
The three registry lookups are now named for what they are keyed by, so that none of them is called registries — a name the registries setting itself has taken:
| before | after |
|---|---|
Config.registries |
Config.registriesByScope |
Config.namedRegistries |
Config.registriesByPrefix |
Config.registryOptions |
Config.registryOptionsByUrl |
The same rename applies to the RegistryContext fields, the Registries and NamedRegistries types (now RegistriesByScope and RegistriesByPrefix), normalizeRegistries / normalizeNamedRegistries (now normalizeRegistriesByScope / normalizeRegistriesByPrefix), and the BUILTIN_NAMED_REGISTRIES constant (now BUILTIN_REGISTRIES_BY_PREFIX).
This is an internal rename: no setting, error code, lockfile field, or .pnpmfile.cjs hook field changes. A preResolution hook still reads ctx.registries, which is the name pacquet passes as well. The registries and namedRegistries settings are read under the names users write them.
The pnpr resolve request sends registriesByPrefix where it sent namedRegistries. A pnpr server and its clients must be on matching versions, which is already the case for an experimental server.
A registry can now declare that its abbreviated metadata carries the time field, so resolutionMode: time-based reads the full metadata document only from the registries that need it:
resolutionMode: time-based
registries:
https://npm.internal.example/:
supportsTimeField: true
registry.npmjs.org omits time from abbreviated metadata, so a time-based resolution has to fall back to the much larger full document. That fallback used to be all-or-nothing: registrySupportsTimeField answered for every registry at once, so a project resolving from both the public registry and a Verdaccio instance either paid for full metadata everywhere or claimed a time field npmjs does not serve. The answer is now per registry, and registrySupportsTimeField remains the answer for every registry that does not declare one.
The declaration is also sent to a pnpr server, which applies it to the resolution it runs on the client's behalf.
The registries setting now declares a registry once, keyed by its URL, with everything about that registry in the entry: how it lays out tarball URLs, the scopes routed to it, and the bare-specifier prefix it answers to.
registries:
https://artifactory.example.com/artifactory/api/npm/npm-virtual/:
serverType: artifactory
scopes: ['@acme', '@acme-internal']
prefix: work
serverType tells pnpm how the registry lays out its tarball URLs, which decides whether a URL can be omitted from pnpm-lock.yaml:
npm — the registry behaves like registry.npmjs.org, which also serves a scoped package from its percent-encoded path. Declare this for a faithful mirror or caching proxy of the public registry so its tarball URLs can be omitted too.artifactory — JFrog Artifactory repeats the scope in a scoped package's tarball filename (@acme/widget/-/@acme/widget-1.0.0.tgz) where the npm registry strips it (@acme/widget/-/widget-1.0.0.tgz). Declaring it lets pnpm rebuild that URL, so it is omitted from pnpm-lock.yaml instead of being written out for every scoped package pnpm/get-npm-tarball-url#16.scopes lists the @-prefixed scopes that resolve from this registry. A bare '@' is the scope-less default registry, the one the registry setting names.prefix is the alias a dependency addresses this registry by, as in "foo": "work:^1.0.0".The layout is never inferred from the registry URL, so nothing changes unless you declare it; registry.npmjs.org continues to behave as npm without being declared. Because the lockfile depends on serverType, it is read from pnpm-workspace.yaml only — a serverType in the global config.yaml is ignored, so one developer's machine cannot shape a lockfile their collaborators read back with a different layout. Credentials are rejected in this setting, in a key as well as in a field, and still belong in .npmrc. An entry that routes nothing to itself and matches no configured registry is reported as a warning rather than silently ignored.
The older registries shape, a map of <scope>: <url> strings, still works and needs no change:
registries:
'@acme': https://npm.acme.example/
namedRegistries is deprecated in favor of the prefix field, and is still read for prefixes registries does not declare.
toLockfileResolution and isCanonicalRegistryTarballUrl now take their registry and layout as an options object rather than positional arguments, so @pnpm/lockfile.utils and @pnpm/resolving.tarball-url get a major bump.
Added virtualStoreType, which names where the virtual store lives — one store per machine, or one per project:
virtualStoreType: global # or: project
It is the canonical spelling of enableGlobalVirtualStore, which keeps working. When a project sets both, virtualStoreType wins. It can also be set through PNPM_CONFIG_VIRTUAL_STORE_TYPE and read back with pnpm config get virtualStoreType. The default is unchanged — project, so the shared store stays opt-in.
The setting is independent of nodeLinker. isolated and pnp both work with either store type, and hoisted writes no virtual store at all, so it is unaffected.
Fixed the order in which pnpm matches a lockfile's recorded tarball URL against known registry URLs. Two registry URLs of equal length were previously
@pnpm/types keeps PinnedVersion as a deprecated alias of RangeSpecStyle. The rename itself changes no CLI behavior; the =-pin handling is described in…
PinnedVersion type to RangeSpecStyle and the pinnedVersion option fields to rangeSpecStyle: the value selects the operator a specifier is saved with, not a pin. whichVersionIsPinned is now inferRangeSpecStyle, and the new rangeSpecGranularity helper collapses the exact spelling to its patch range width. @pnpm/types keeps PinnedVersion as a deprecated alias of RangeSpecStyle. The rename itself changes no CLI behavior; the =-pin handling is described in its own changesets.pnpm update keeps the explicit = operator of an exact version pin: a dependency saved as =3.5.1 now updates to =3.5.2 instead of the bare 3.5.2. See pnpm/pnpm#13168.Added support for publishConfig.name, which publishes a package under a different name than the one its manifest carries in the workspace. It is for a
publishConfig.name, which publishes a package under a different name than the one its manifest carries in the workspace. It is for a project whose published name is already taken by a sibling project, which otherwise has to be renamed by a build step just before publishing. Only the published artifact is renamed — dependents, pnpm-lock.yaml, and release tooling keep addressing the project by its manifest name — and the new name reaches the packed manifest, the tarball filename, and everything that addresses the package at the registry: the already-published check of pnpm publish -r, its registry selection, and the release-planning probes of pnpm change status and pnpm version -r #13345.Checking GitHub Actions dependencies for updates is now opt-in for every command. Neither pnpm outdated nor pnpm update reads the workflow files unless --include-github-actions is passed or update.githubActions is set to true in pnpm-workspace.yaml. Reading them runs git ls-remote against every referenced repository, which fails in environments where GitHub is not reachable the way pnpm assumes (a GitHub Enterprise Server, a custom certificate authority, or an offline network) #13254.
pnpm outdated accepts the --include-github-actions option too.
Added a new setting, update.githubActionsServer, for specifying the base URL of the GitHub server that hosts the repositories of the GitHub Actions re
Added a new setting, update.githubActionsServer, for specifying 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). When the setting is not defined, the URL is read from the GITHUB_SERVER_URL environment variable, falling back to https://github.com. The URL must use the https:// or http:// protocol #13220.
pnpm outdated and pnpm update no longer fail when the refs of a GitHub Action's repository cannot be read (for example, when the action's repository is private or hosted on a different GitHub server). Such actions are now skipped with a warning.
Setting update.githubActions to false now makes pnpm outdated and the interactive pnpm update skip GitHub Actions dependencies.
The deprecated updateConfig, auditConfig, and auditLevel settings keep working until the next major version. When both a new section value and its dep…
Added GitHub Actions dependencies to pnpm outdated and interactive pnpm update. Non-interactive updates can include them with --include-github-actions or by setting update.githubActions to true in pnpm-workspace.yaml. Updated actions are pinned to exact commit hashes with their release tags preserved in comments.
Added update and audit settings sections to pnpm-workspace.yaml, superseding the awkwardly named updateConfig, auditConfig, and top-level auditLevel settings:
update:
ignoreDeps: # was updateConfig.ignoreDependencies
- webpack
- "@babel/*"
audit:
level: high # was auditLevel
ignore: # was auditConfig.ignoreGhsas
- GHSA-xxxx-yyyy-zzzz
update.ignoreDeps lists dependency name patterns that pnpm update and pnpm outdated should skip. audit.level and audit.ignore tune pnpm audit.
The deprecated updateConfig, auditConfig, and auditLevel settings keep working until the next major version. When both a new section value and its deprecated counterpart are set, the new section takes precedence and a warning is printed. Both the TypeScript CLI and the Rust config surface (pacquet) recognize the new sections.
Added versioning.epics to pnpm-workspace.yaml. An epic ties a group of member packages to a lead package, constraining every member's major version to
Added versioning.epics to pnpm-workspace.yaml. An epic ties a group of member packages to a lead package, constraining every member's major version to a band derived from the lead's major: while the lead is on major M, members live in M*100 … M*100+99. Members move independently inside the band (patch, minor, and a major intent that stays in-band); a bump that would carry a member past the band ceiling is rejected until the lead advances its own major. When a release plan takes the lead to a new stable major, every member re-bases to the band floor in the same plan. Membership is matched with pnpm's package selectors — name globs, ./-prefixed directory globs, and !-prefixed negations.
Added native workspace release management #12952: the new pnpm change command records change intents as changesets-compatible .changeset/*.md files (pnpm change status shows the pending release plan), and the bare pnpm version -r consumes them — bumping versions across the workspace with dependent propagation through workspace: ranges, fixed groups, a maxBump cap, --filter narrowing, and --dry-run — writing changelogs, and recording consumed intents in a committed ledger that keeps cherry-picks and merge-backs between release branches safe. Packages can be moved onto per-package release lanes with the new pnpm lane <name> --filter <pkg> command and back with pnpm lane main --filter <pkg> (pnpm lane shows the membership), releasing X.Y.Z-lane.N prereleases from the same runs that release stable versions of the packages on the main lane. Configuration lives under the new versioning key of pnpm-workspace.yaml (fixed, ignore, maxBump, lanes, changelog). When two workspace projects publish the same name, intent files, versioning.lanes, and versioning.fixed/ignore may reference a project by its workspace-relative directory path (e.g. "./pnpm/npm/pnpm") — the one additive extension to the changesets format, applied automatically by pnpm change.
Release changelogs default to registry storage (versioning.changelog.storage): no CHANGELOG.md is committed. Each release's section is composed at publish time and packed into the published tarball on top of the previously published version's changelog, and the consumed change intents are garbage-collected by a later pnpm version -r only once the registry confirms the version is published with its section. Set versioning.changelog.storage: repository to keep committed CHANGELOG.md files instead.
681b593: pnpm can now use different auth tokens for different package scopes, even when those scopes use the same registry URL.
681b593: pnpm can now use different auth tokens for different package scopes, even when those scopes use the same registry URL.
Previously, auth was selected only by registry URL. If @org-a and @org-b both used https://npm.pkg.github.com/, they had to share the same token. This caused problems for registries that issue tokens per organization or per scope.
Configure a scope-specific token by adding the package scope after the registry URL in the auth key:
@org-a:registry=https://npm.pkg.github.com/
@org-b:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:@org-a:_authToken=${ORG_A_TOKEN}
//npm.pkg.github.com/:@org-b:_authToken=${ORG_B_TOKEN}
//npm.pkg.github.com/:_authToken=${FALLBACK_TOKEN}
pnpm login --registry=https://npm.pkg.github.com --scope=@org-a writes the token to the same scope-specific auth key.
When installing or publishing @org-a/*, pnpm uses ORG_A_TOKEN. For @org-b/*, pnpm uses ORG_B_TOKEN. Packages without a matching scope continue to use the registry-wide fallback token.
bf1b731: Require trusted package identity before package-name allowBuilds entries can approve lifecycle scripts for git, git-hosted tarball, direct ta
allowBuilds entries can approve lifecycle scripts for git, git-hosted tarball, direct tarball, and local directory artifacts. To approve one of those artifacts explicitly, use its peer-suffix-free lockfile depPath as the allowBuilds key. Lockfile verification now rejects lockfiles where a registry-style dependency path (name@semver) is backed by a git, directory, or git-hosted tarball resolution (ERR_PNPM_RESOLUTION_SHAPE_MISMATCH), so the dependency path is a reliable artifact identity by the time scripts can run.a017bf3: Renamed the experimental agent setting to pnprServer so the pnpm CLI matches the same setting name pacquet uses for offloading resolution to
agent setting to pnprServer so the pnpm CLI matches the same setting name pacquet uses for offloading resolution to a pnpr server. Point pnpm at a pnpr server with pnprServer: <url> in pnpm-workspace.yaml (or --pnpr-server <url>); the previous agent / --agent name no longer works. The client package was likewise renamed from @pnpm/agent.client to @pnpm/pnpr.client.35d2355: Validate devEngines.runtime and engines.runtime version ranges for node, deno, and bun when onFail is set to error or warn. Previously these
devEngines.runtime and engines.runtime version ranges for node, deno, and bun when onFail is set to error or warn. Previously these settings only had an effect with onFail: 'download' — the error and warn modes silently did nothing #11818. Violations now throw ERR_PNPM_BAD_RUNTIME_VERSION.64afc92: Honor publishConfig.access when publishing packages.
publishConfig.access when publishing packages.b61e268: Added support for installing packages from the GitHub Packages npm registry via a built-in gh: prefix (e.g. pnpm add gh:@acme/private), and,
b61e268: Added support for installing packages from the GitHub Packages npm registry via a built-in gh: prefix (e.g. pnpm add gh:@acme/private), and, more broadly, for arbitrary named registries in the style of vlt's named-registry aliases. 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.
Additional aliases — or an override for the built-in gh alias, for GitHub Enterprise Server — can be configured under namedRegistries in pnpm-workspace.yaml:
namedRegistries:
gh: https://npm.pkg.github.example.com/
work: https://npm.work.example.com/
With this, work:@corp/lib@^2.0.0 resolves against https://npm.work.example.com/. #8941.
The bulk endpoint does not return CVE identifiers. CVE-based filtering has been replaced with GitHub advisory ID (GHSA) filtering:
ff28085: pnpm audit now calls npm's /-/npm/v1/security/advisories/bulk endpoint. The legacy /-/npm/v1/security/audits{,/quick} endpoints have been retired by the registry, so the legacy request/response contract is no longer supported.
The bulk endpoint does not return CVE identifiers. CVE-based filtering has been replaced with GitHub advisory ID (GHSA) filtering:
auditConfig.ignoreCves → auditConfig.ignoreGhsas (the previous key is no longer recognized)pnpm audit --ignore <id> / pnpm audit --ignore-unfixable now read and write GHSAs instead of CVEsurl (https://github.com/advisories/GHSA-xxxx-xxxx-xxxx)To migrate: replace each CVE-YYYY-NNNNN entry in your auditConfig.ignoreCves with the corresponding GHSA-xxxx-xxxx-xxxx value (visible in the More info column of pnpm audit output) and move it under auditConfig.ignoreGhsas.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
15549a9: Add the ability to fix vulnerabilities by updating packages in the lockfile instead of adding overrides.
onlyBuiltDependencies, onlyBuiltDependenciesFile, neverBuiltDependencies, and ignoredBuiltDependencies.allowNonAppliedPatches completely in favor of allowUnusedPatches.
Remove ignorePatchFailures so all patch application failures should throw an error.useNodeVersion and executionEnv.nodeVersion fields. devEngines.runtime and engines.runtime should be used instead #10373.76718b3: Added support for allowBuilds, which is a new field that can be used instead of onlyBuiltDependencies and ignoredBuiltDependencies. The new allowBuilds field in your pnpm-workspace.yaml uses a map of package matchers to explicitly allow (true) or disallow (false) script execution. This allows for a single, easy-to-manage source of truth for your build permissions.
Example Usage. To explicitly allow all versions of esbuild to run scripts and prevent core-js from running them:
allowBuilds:
esbuild: true
core-js: false
The example above achieves the same result as the previous configuration:
onlyBuiltDependencies:
- esbuild
ignoredBuiltDependencies:
- core-js
Related PR: #10311
cc1b8e3: Fixed installation of config dependencies from private registries.
Added support for object type in configDependencies when the tarball URL returned from package metadata differs from the computed URL #10431.
05fb1ae: Add type for IgnoredBuilds.
10bc391: Added a new setting: trustPolicy.
2df8b71: pnpm no longer reads all settings from .npmrc. Only auth and registry settings are read from .npmrc files. All other settings (like hoist-pattern, node-linker, shamefully-hoist, etc.) must be configured in pnpm-workspace.yaml or the global ~/.config/pnpm/config.yaml.
.npmrc is now only for auth and registry settings. pnpm-specific settings in .npmrc are ignored. Move them to pnpm-workspace.yaml.
pnpm no longer reads npm_config_* environment variables. Use pnpm_config_* environment variables instead (e.g., pnpm_config_registry instead of npm_config_registry).
pnpm no longer reads the npm global config at $PREFIX/etc/npmrc.
pnpm login writes auth tokens to ~/.config/pnpm/auth.ini.
.npmrcThe following settings continue to be read from .npmrc files (project-level and ~/.npmrc):
registry and @scope:registry — registry URLs//registry.example.com/:_authToken — auth tokens per registry_auth, _authToken, _password, username, email — global auth credentials//registry.example.com/:tokenHelper — token helper commandsca, cafile, cert, key, certfile, keyfile — SSL certificatesstrict-ssl — SSL verificationproxy, https-proxy, no-proxy — proxy settingslocal-address — local network address bindinggit-shallow-hosts — git shallow clone hostsnpmrcAuthFile settingA new npmrcAuthFile setting can be added to pnpm-workspace.yaml or ~/.config/pnpm/config.yaml to specify a custom path to the user .npmrc file (defaults to ~/.npmrc):
npmrcAuthFile: /custom/path/.npmrc
registries setting in pnpm-workspace.yamlRegistry URLs can now be configured in pnpm-workspace.yaml, so there's no need to commit .npmrc files with registry mappings:
registries:
default: https://registry.npmjs.org/
"@my-org": https://private.example.com/
"@internal": https://nexus.corp.com/
This replaces the .npmrc settings registry=... and @scope:registry=....
~/.config/pnpm/auth.ini — pnpm's own auth file (written by pnpm login)<workspace>/.npmrc — workspace root (or project root)~/.npmrc (or custom npmrcAuthFile) — user-level fallbackNote: .npmrc is only read from the workspace root, not from individual package directories.
Move pnpm settings from .npmrc to pnpm-workspace.yaml:
Before (.npmrc):
shamefully-hoist=true
node-linker=hoisted
After (pnpm-workspace.yaml):
shamefullyHoist: true
nodeLinker: hoisted
Move scoped registry mappings from .npmrc to pnpm-workspace.yaml:
Before (.npmrc):
@my-org:registry=https://private.example.com
After (pnpm-workspace.yaml):
registries:
"@my-org": https://private.example.com/
If you use npm_config_* env vars, switch to pnpm_config_*:
# Before
npm_config_registry=https://registry.example.com
# After
pnpm_config_registry=https://registry.example.com
Auth tokens in ~/.npmrc still work. No migration needed for registry authentication — pnpm continues to read ~/.npmrc as a fallback.
15549a9: Add the ability to fix vulnerabilities by updating packages in the lockfile instead of adding overrides.
cc7c0d2: pnpm publish now works without the npm CLI.
The One-time Password feature now reads from PNPM_CONFIG_OTP instead of NPM_CONFIG_OTP:
export PNPM_CONFIG_OTP='<your OTP here>'
pnpm publish --no-git-checks
If the registry requests OTP and the user has not provided it via the PNPM_CONFIG_OTP environment variable or the --otp flag, pnpm will prompt the user directly for an OTP code.
If the registry requests web-based authentication, pnpm will print a scannable QR code along with the URL.
Since the new pnpm publish no longer calls npm publish, some undocumented features may have been unknowingly dropped. If you rely on a feature that is now gone, please open an issue at https://github.com/pnpm/pnpm/issues. In the meantime, you can use pnpm pack && npm publish *.tgz as a workaround.
efb48dc: Node.js Runtime Installation for Dependencies. Added support for automatic Node.js runtime installation for dependencies. pnpm will now install the Node.js version required by a dependency if that dependency declares a Node.js runtime in the "engines" field. For example:
{
"engines": {
"runtime": {
"name": "node",
"version": "^24.11.0",
"onFail": "download"
}
}
}
If the package with the Node.js runtime dependency is a CLI app, pnpm will bind the CLI app to the required Node.js version. This ensures that, regardless of the globally installed Node.js instance, the CLI will use the compatible version of Node.js.
If the package has a postinstall script, that script will be executed using the specified Node.js version.
Related PR: #10141
pnpm-lock.yaml instead of inlining it in pnpm-workspace.yaml. The workspace manifest now contains only clean version specifiers for configDependencies, while the resolved versions, integrity hashes, and tarball URLs are recorded in the lockfile as a separate YAML document. The env lockfile section also stores packageManagerDependencies resolved during version switching and self-update. Projects using the old inline-hash format are automatically migrated on install.pnpm list and pnpm why now display npm: protocol for aliased packages (e.g., foo npm:is-odd@3.0.1) #8660.7c1382f: Add PackageVersionPolicy function type.
7c1382f: Add PackageVersionPolicy function type.
dee39ec: You can now allow specific versions of dependencies to run postinstall scripts. onlyBuiltDependencies now accepts package names with lists of trusted versions. For example:
onlyBuiltDependencies:
- nx@21.6.4 || 21.6.5
- esbuild@0.25.1
Related PR: #10104.
e792927: Added support for finders #9946.
finders #9946.1a07b8f: Added "devEngines" to the manifest fields.
### Minor Changes - 5ec7255: Export AuditConfig.
### Minor Changes - 5b73df1: Added PinnedVersion.
PinnedVersion.750ae7d: Export ConfigDependencies type.
ConfigDependencies type.5f7be64: Rename pnpm.allowNonAppliedPatches to pnpm.allowUnusedPatches. The old name is still supported but it would print a deprecation warning messa…
5f7be64: Rename pnpm.allowNonAppliedPatches to pnpm.allowUnusedPatches. The old name is still supported but it would print a deprecation warning message.
5f7be64: Add pnpm.ignorePatchFailures to manage whether pnpm would ignore patch application failures.
If ignorePatchFailures is not set, pnpm would throw an error when patches with exact versions or version ranges fail to apply, and it would ignore failures from name-only patches.
If ignorePatchFailures is explicitly set to false, pnpm would throw an error when any type of patch fails to apply.
If ignorePatchFailures is explicitly set to true, pnpm would print a warning when any type of patch fails to apply.
a5e4965: Fix pnpm deploy creating a package.json without the imports and license field #9193.
pnpm deploy creating a package.json without the imports and license field #9193.### Minor Changes - 8fcc221: Export PnpmSettings.
b562deb: Fix pnpm deploy creating a package.json without the "type" key #8962.
pnpm deploy creating a package.json without the "type" key #8962.9591a18: Added support for a new type of dependencies called "configurational dependencies". These dependencies are installed before all the other typ
9591a18: Added support for a new type of dependencies called "configurational dependencies". These dependencies are installed before all the other types of dependencies (before "dependencies", "devDependencies", "optionalDependencies").
Configurational dependencies cannot have dependencies of their own or lifecycle scripts. They should be added using exact version and the integrity checksum. Example:
{
"pnpm": {
"configDependencies": {
"my-configs": "1.0.0+sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="
}
}
}
Nothing published for this version
Nothing published for this version
d500d9f: Added a new setting to package.json at pnpm.auditConfig.ignoreGhsas for ignoring vulnerabilities by their GHSA code #6838.
d500d9f: Added a new setting to package.json at pnpm.auditConfig.ignoreGhsas for ignoring vulnerabilities by their GHSA code #6838.
For instance:
{
"pnpm": {
"auditConfig": {
"ignoreGhsas": [
"GHSA-42xw-2xvc-qx8m",
"GHSA-4w2v-q235-vp99",
"GHSA-cph5-m8f7-6c5x",
"GHSA-vh95-rmgr-6w4m"
]
}
}
}
7ee59a1: Added optional modulesDir field to projects.
cb006df: Add ability to apply patch to all versions: If the key of pnpm.patchedDependencies is a package name without a version (e.g. pkg), pnpm will
cb006df: Add ability to apply patch to all versions:
If the key of pnpm.patchedDependencies is a package name without a version (e.g. pkg), pnpm will attempt to apply the patch to all versions of
the package, failure will be skipped.
If it is a package name and an exact version (e.g. pkg@x.y.z), pnpm will attempt to apply the patch to that exact version only, failure will
cause pnpm to fail.
If there's only one version of pkg installed, pnpm patch pkg and subsequent pnpm patch-commit $edit_dir will create an entry named pkg in
pnpm.patchedDependencies. And pnpm will attempt to apply this patch to other versions of pkg in the future.
If there's multiple versions of pkg installed, pnpm patch pkg will ask which version to edit and whether to attempt to apply the patch to all.
If the user chooses to apply the patch to all, pnpm patch-commit $edit_dir would create a pkg entry in pnpm.patchedDependencies.
If the user chooses not to apply the patch to all, pnpm patch-commit $edit_dir would create a pkg@x.y.z entry in pnpm.patchedDependencies with
x.y.z being the version the user chose to edit.
If the user runs pnpm patch pkg@x.y.z with x.y.z being the exact version of pkg that has been installed, pnpm patch-commit $edit_dir will always
create a pkg@x.y.z entry in pnpm.patchedDependencies.
> Migration guide: Migrating from v10 to v11
See full v11.0.0 changelog Migration guide: Migrating from v10 to v11
Added pnpm audit signatures to verify ECDSA registry signatures for installed packages against keys from /-/npm/v1/keys #7909. Scoped registries are respected, and registries without signing keys are skipped.
Added support for installing packages from the GitHub Packages npm registry via a built-in gh: prefix (e.g. pnpm add gh:@acme/private), and, more broadly, for arbitrary named registries in the style of vlt's named-registry aliases. 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.
Additional aliases — or an override for the built-in gh alias, for GitHub Enterprise Server — can be configured under namedRegistries in pnpm-workspace.yaml:
namedRegistries:
gh: https://npm.pkg.github.example.com/
work: https://npm.work.example.com/
With this, work:@corp/lib@^2.0.0 resolves against https://npm.work.example.com/. #11324.
Allow setting sbom spec version using --sbom-spec-version #11389.
Add --no-runtime flag (config: runtime=false) to skip installing runtime entries (e.g. Node.js downloaded via devEngines.runtime) without modifying the lockfile. The lockfile keeps the runtime entry so frozen-lockfile validation still passes; only the runtime fetch and .bin linking are skipped. Useful in CI matrices where the runtime is provisioned externally (e.g. via pnpm runtime -g set node <version>) before pnpm install runs.
Added the pnpm bugs command that opens a package's bug tracker URL in the browser. With no arguments, it reads the current project's package.json; with one or more package names, it fetches each package's metadata from the registry and opens its bug tracker. Falls back to <repository>/issues when the bugs field is missing #11279.
Added pnpm owner command to manage package owners on the registry.
Added "published X ago by Y" information to the pnpm view command output, similar to npm view. This is useful when comparing against minimumReleaseAge.
For example, pnpm view pnpm now shows:
published 17 hours ago by GitHub Actions
pnpm publish now honors the configured HTTP/HTTPS proxy (including https_proxy/http_proxy/no_proxy environment variables) when polling the registry's doneUrl during the web-based authentication flow. Previously the poll bypassed the proxy, causing the registry to respond 403 from a different source IP and the login to never complete #11561.
pnpm add -g now installs each space-separated package into its own isolated directory by default. To bundle multiple packages into the same isolated install (so that they share dependencies and are removed together), pass them as a comma-separated list. For example:
pnpm add -g foo bar installs foo and bar as two independent globals — removing one does not affect the other.pnpm add -g foo,bar qar bundles foo and bar into a single isolated install while qar is installed on its own.Related: #11587.
pnpm runtime set <name> <version> no longer fails in the root of a multi-package workspace with the ADDING_TO_ROOT error. Installing the workspace root is a valid target for a runtime, so the command now bypasses that safety check.
Fix pnpm --version hanging for the lifetime of the worker pool after the version was printed. main.ts's --version short-circuit returned before reaching the command-handler finally that calls finishWorkers(), so the worker pool that switchCliVersion had spawned during integrity resolution stayed alive and held the Node event loop open. The CLI entry now runs finishWorkers() from its own finally, so every exit path tears the pool down.
Repro: pnpm --version in a workspace whose devEngines.packageManager version already matches the running pnpm + onFail: "download". switchCliVersion resolves the integrity (spawning workers), finds nothing to swap, returns. The version prints, then the process hangs.
<!-- sponsors -->
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/sanity.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/sanity_light.svg" /> <img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" /> <img src="https://pnpm.io/img/users/discord.svg" width="220" alt="Discord" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/serpapi_dark.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/serpapi_light.svg" /> <img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160" alt="SerpApi" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" /> <img src="https://pnpm.io/img/users/coderabbit.svg" width="220" alt="CodeRabbit" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/stackblitz.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/stackblitz_light.svg" /> <img src="https://pnpm.io/img/users/stackblitz.svg" width="190" alt="Stackblitz" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/workleap.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/workleap_light.svg" /> <img src="https://pnpm.io/img/users/workleap.svg" width="190" alt="Workleap" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" /> <img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" /> </picture> </a> </td> </tr> </tbody> </table>
<!-- sponsors end -->
pnpm.executionEnv.nodeVersion in package.json) for running lifecycle scripts per each package in a workspace #6720.…the legacy /security/audits endpoints are gone. CVE-based filtering has been replaced with GHSA-based filtering: migrate auditConfig.ignoreCves entrie…
Migration guide: Migrating from v10 to v11
minimumReleaseAge defaults to 1 day (newly published packages are not resolved for 24h) and blockExoticSubdeps defaults to true.allowBuilds replaces the old build-dependency settings — onlyBuiltDependencies, onlyBuiltDependenciesFile, neverBuiltDependencies, ignoredBuiltDependencies, and ignoreDepScripts have been removed.pnpm add -g gets its own directory with its own package.json, node_modules, and lockfile.pnpm publish, login, logout, view, deprecate, unpublish, dist-tag, and version no longer delegate to the npm CLI, and the remaining npm passthrough commands now throw "not implemented".pnpm audit uses npm's bulk advisories endpoint — the legacy /security/audits endpoints are gone. CVE-based filtering has been replaced with GHSA-based filtering: migrate auditConfig.ignoreCves entries to auditConfig.ignoreGhsas..npmrc is auth/registry only — all other settings must live in pnpm-workspace.yaml or the new global config.yaml, and environment variables use the pnpm_config_* prefix.node@runtime:<version> no longer extracts the bundled npm, npx, and corepack, roughly halving the files pnpm has to hash, write, and link.pnpm ci, pnpm sbom, pnpm clean, pnpm peers check, pnpm runtime set, pnpm docs/home, pnpm ping, pnpm search, pnpm star/unstar/stars, pnpm whoami, pnpm with, and pnpm pack-app, plus pn/pnx short aliases..pnpmfile.mjs, which takes priority over .pnpmfile.cjs when present.pnpm audit --fix=update fixes vulnerabilities by updating packages in the lockfile instead of adding overrides, and pnpm audit --fix --interactive lets you select which advisories to fix.pnpm pack-app packs a CommonJS entry into a standalone executable for one or more target platforms using Node.js Single Executable Applications.Changed default values: optimisticRepeatInstall is now true, verifyDepsBeforeRun is now install, minimumReleaseAge is now 1440 (1 day), and minimumReleaseAgeStrict is false. Newly published packages will not be resolved until they are at least 1 day old. This protects against supply chain attacks by giving the community time to detect and remove compromised versions. To opt out, set minimumReleaseAge: 0 in pnpm-workspace.yaml #11158.
strictDepBuilds is true by default.
blockExoticSubdeps is true by default.
Removed deprecated build dependency settings: onlyBuiltDependencies, onlyBuiltDependenciesFile, neverBuiltDependencies, ignoredBuiltDependencies, and ignoreDepScripts #11220.
Use the allowBuilds setting instead. It is a map where keys are package name patterns and values are booleans:
true means the package is allowed to run build scriptsfalse means the package is explicitly denied from running build scriptsSame as before, by default, none of the packages in the dependencies are allowed to run scripts. If a package has postinstall scripts and it isn't declared in allowBuilds, an error is printed.
Before:
onlyBuiltDependencies:
- electron
onlyBuiltDependenciesFile: "allowed-builds.json"
neverBuiltDependencies:
- core-js
ignoredBuiltDependencies:
- esbuild
After:
allowBuilds:
electron: true
core-js: false
esbuild: false
Removed allowNonAppliedPatches in favor of allowUnusedPatches.
Removed ignorePatchFailures; patch application failures now throw an error.
<algo>-<digest>). Using hex format improves performance since file paths in the content-addressable store use hex representation, eliminating base64-to-hex conversion during path lookups.package.json from the content-addressable store during resolution and installation. This reduces I/O and speeds up repeat installs #10473.$STORE/index/, package metadata is stored in a single SQLite database at $STORE/index.db with MessagePack-encoded values. This reduces filesystem syscall overhead, improves space efficiency for small metadata entries, and enables concurrent access via SQLite's WAL mode. Packages missing from the new index are re-fetched on demand #10500 #10826.Global installs (pnpm add -g pkg) and pnx now use the global virtual store by default. Packages are stored at {storeDir}/links instead of per-project .pnpm directories. This can be disabled by setting enableGlobalVirtualStore: false #10694.
Isolated global packages. Each globally installed package (or group of packages installed together) now gets its own isolated installation directory with its own package.json, node_modules/, and lockfile. This prevents global packages from interfering with each other through peer dependency conflicts, hoisting changes, or version resolution shifts.
Key changes:
pnpm add -g <pkg> creates an isolated installation in {pnpmHomeDir}/global/v11/{hash}/pnpm remove -g <pkg> removes the entire installation group containing the packagepnpm update -g [pkg] re-installs packages in new isolated directoriespnpm list -g scans isolated directories to show all installed global packagespnpm install -g (no args) is no longer supported; use pnpm add -g <pkg> insteadGlobally installed binaries are now stored in a bin subdirectory of PNPM_HOME instead of directly in PNPM_HOME. This prevents internal directories like global/ and store/ from polluting shell autocompletion when PNPM_HOME is on PATH #10986. After upgrading, run pnpm setup to update your shell configuration.
Breaking changes to pnpm link:
pnpm link <pkg-name> no longer resolves packages from the global store. Only relative or absolute paths are accepted. For example, use pnpm link ./foo instead of pnpm link foo.pnpm link --global is removed. Use pnpm add -g . to register a local package's bins globally.pnpm link (no arguments) is removed. Use pnpm link <dir> with an explicit path instead.pnpm no longer reads all settings from .npmrc. Only auth and registry settings are read from .npmrc files. All other settings (like hoistPattern, nodeLinker, shamefullyHoist, etc.) must be configured in pnpm-workspace.yaml or the global ~/.config/pnpm/config.yaml #11189.
Network settings (httpProxy, httpsProxy, noProxy, localAddress, strictSsl, gitShallowHosts) are now written to config.yaml (global) or pnpm-workspace.yaml (local) instead of .npmrc/auth.ini. They are still readable from .npmrc for easier migration from the npm CLI #11209.
pnpm no longer reads npm_config_* environment variables. Use pnpm_config_* environment variables instead (e.g., pnpm_config_registry instead of npm_config_registry).
pnpm no longer reads the npm global config at $PREFIX/etc/npmrc.
pnpm login writes auth tokens to ~/.config/pnpm/auth.ini.
New registries setting in pnpm-workspace.yaml:
registries:
default: https://registry.npmjs.org/
"@my-org": https://private.example.com/
"@internal": https://nexus.corp.com/
Auth tokens in ~/.npmrc still work — pnpm continues to read ~/.npmrc as a fallback for registry authentication. The new npmrcAuthFile setting can be used to point to a different file instead of ~/.npmrc.
Replace workspace project specific .npmrc with packageConfigs in pnpm-workspace.yaml.
A workspace manifest with packageConfigs looks something like this:
# File: pnpm-workspace.yaml
packages:
- "packages/project-1"
- "packages/project-2"
packageConfigs:
"project-1":
saveExact: true
"project-2":
savePrefix: "~"
Or this:
# File: pnpm-workspace.yaml
packages:
- "packages/project-1"
- "packages/project-2"
packageConfigs:
- match: ["project-1", "project-2"]
modulesDir: "node_modules"
saveExact: true
pnpm no longer reads settings from the pnpm field of package.json. Settings should be defined in pnpm-workspace.yaml #10086.
pnpm config get (without --json) no longer prints INI formatted text. Instead, it prints JSON for objects and arrays, and raw strings for strings, numbers, booleans, and nulls. pnpm config get --json still prints all types of values as JSON, as before.
pnpm config get <array> now prints a JSON array.
pnpm config list now prints a JSON object instead of INI formatted text.
pnpm config list and pnpm config get (without argument) now hide auth-related settings.
pnpm config list and pnpm config get (without argument) now show top-level keys as camelCase. Exception: keys that start with @ or // are preserved (their cases don't change).
pnpm config get and pnpm config list no longer load non-camelCase options from the workspace manifest (pnpm-workspace.yaml).
pnpm no longer falls back to the npm CLI. Commands that were previously passed through to npm (access, bugs, docs, edit, find, home, issues, owner, ping, prefix, profile, pkg, repo, search, set-script, star, stars, team, token, unstar, whoami, xmas) and their aliases (s, se) now throw a "not implemented" error, with a suggestion to use the npm CLI directly #10642. Other previously passed-through commands — view (info, show, v), login (adduser), logout, deprecate, unpublish, dist-tag, and version — have been reimplemented natively in pnpm (see New Commands below).
pnpm publish now works without the npm CLI.
The One-time Password feature now reads from PNPM_CONFIG_OTP instead of NPM_CONFIG_OTP:
export PNPM_CONFIG_OTP='<your OTP here>'
pnpm publish --no-git-checks
If the registry requests OTP and the user has not provided it via the PNPM_CONFIG_OTP environment variable or the --otp flag, pnpm will prompt the user directly for an OTP code.
If the registry requests web-based authentication, pnpm will print a scannable QR code along with the URL.
Since the new pnpm publish no longer calls npm publish, some undocumented features may have been unknowingly dropped. If you rely on a feature that is now gone, please open an issue at https://github.com/pnpm/pnpm/issues. In the meantime, you can use pnpm pack && npm publish *.tgz as a workaround.
Removed the pnpm server command #10463.
Removed support for the useNodeVersion and executionEnv.nodeVersion fields. devEngines.runtime and engines.runtime should be used instead #10373.
Removed support for hooks.fetchers. We now have a new API for custom fetchers and resolvers via the fetchers field of pnpmfile.
npm_config_* environment variables from the pnpm config during lifecycle scripts. Only well-known npm_* env vars are now set, matching Yarn's behavior #11116.$ command instead of > pkg@version stage path\n> command, and shows project name and path only when running in a different directory. The $ command line is printed to stderr to keep stdout clean for piping #11132.pnpm peers check to view the issues #11133.patchedDependencies lockfile format from Record<string, { path: string, hash: string }> to Record<string, string> (selector to hash). Existing lockfiles with the old format are automatically migrated #10911.The default value of the type field in the package.json file of the project initialized by pnpm init command has been changed to module.
Added support for lowercase options in pnpm add: -d, -p, -o, -e #9197.
When using the pnpm add command only:
-p is now an alias for --save-prod instead of --parseable-d is now an alias for --save-dev instead of --loglevel=infoThe root workspace project is no longer excluded when it is explicitly selected via a filter #10465.
pnpm audit now calls npm's /-/npm/v1/security/advisories/bulk endpoint. The legacy /-/npm/v1/security/audits{,/quick} endpoints have been retired by the registry, so the legacy request/response contract is no longer supported.
The bulk endpoint does not return CVE identifiers. CVE-based filtering has been replaced with GitHub advisory ID (GHSA) filtering:
auditConfig.ignoreCves → auditConfig.ignoreGhsas (the previous key is no longer recognized)pnpm audit --ignore <id> / pnpm audit --ignore-unfixable now read and write GHSAs instead of CVEsurl (https://github.com/advisories/GHSA-xxxx-xxxx-xxxx)To migrate: replace each CVE-YYYY-NNNNN entry in your auditConfig.ignoreCves with the corresponding GHSA-xxxx-xxxx-xxxx value (visible in the More info column of pnpm audit output) and move it under auditConfig.ignoreGhsas.
Breaking: removed the managePackageManagerVersions, packageManagerStrict, and packageManagerStrictVersion settings. They existed only to derive the onFail behavior for the legacy packageManager field, and the pmOnFail setting introduced alongside pnpm with subsumes all three — it directly sets the onFail behavior of both packageManager and devEngines.packageManager. The COREPACK_ENABLE_STRICT environment variable is no longer honored (it only gated packageManagerStrict); use pmOnFail instead.
Migration:
| Removed setting | Replace with |
|---|---|
managePackageManagerVersions: true |
pmOnFail: download (default) |
managePackageManagerVersions: false |
pmOnFail: ignore |
packageManagerStrict: false |
pmOnFail: warn |
packageManagerStrictVersion: true |
pmOnFail: error |
COREPACK_ENABLE_STRICT=0 |
pmOnFail: warn |
node@runtime:<version> (including pnpm env use and pnpm runtime set node) no longer extracts the bundled npm, npx, and corepack from the Node.js archive. This cuts roughly half of the files pnpm has to hash, write to the CAS, and link during installation, making runtime installs noticeably faster. Users who still need npm can install it as a separate package.pnpm view (info, show, v) command for viewing package metadata from the registry #11064.pnpm login (and pnpm adduser alias) command for authenticating with npm registries. Supports web-based login with QR code as well as classic username/password login #11094.pnpm logout command for logging out of npm registries. Revokes the authentication token on the registry and removes it from the local auth config file #11213.pnpm deprecate and pnpm undeprecate commands for setting and removing deprecation messages on package versions without delegating to the npm CLI #11120.pnpm unpublish command. Supports unpublishing specific versions, version ranges via semver, and entire packages with --force #11128.pnpm dist-tag command (ls, add, rm subcommands) #11218.pnpm sbom command for generating Software Bill of Materials in CycloneDX 1.7 and SPDX 2.3 JSON formats #9088.pnpm clean command that safely removes node_modules directories from all workspace projects #10707. Use --lockfile to also remove pnpm-lock.yaml files.pnpm runtime set <runtime name> <runtime version spec> [-g] for installing runtimes. Deprecated pnpm env use in favor of the new command.pnpm audit --fix=update #10341.pnpm ci command for clean installs #6100. The command runs pnpm clean followed by pnpm install --frozen-lockfile. Designed for CI/CD environments where reproducible builds are critical. Aliases: pnpm clean-install, pnpm ic, pnpm install-clean #11003.pnpm peers check command that checks for unmet and missing peer dependency issues by reading the lockfile #7087.version command natively in pnpm to support workspaces and workspace: protocols correctly. The new command allows bumping package versions (major, minor, patch, etc.) with full workspace support and git integration #10879.pnpm audit --fix now supports a new interactive mode via --interactive/-i.pnpm docs command and its alias pnpm home. This command opens the package documentation or homepage in the browser. When the package has no valid homepage, it falls back to https://npmx.dev/package/<name>.pnpm ping command to test registry connectivity. Provides a simple way to verify connectivity to the configured registry without requiring external tools.search command and its aliases (s, se, find).star, unstar, stars, and whoami commands.pnpm with <version|current> <args...> command. Runs pnpm at a specific version (or the currently active one) for a single invocation, bypassing the project's packageManager and devEngines.packageManager pins.pnpm pack-app command that packs a CommonJS entry file into a standalone executable for one or more target platforms, using the Node.js Single Executable Applications API under the hood.Added support for a global YAML config file named config.yaml.
Configuration is now split into two categories:
rc file and local .npmrc.config.yaml and local pnpm-workspace.yaml.Added support for loading environment variables whose names start with pnpm_config_ into config. These environment variables override settings from pnpm-workspace.yaml but not CLI arguments.
Added support for reading allowBuilds from pnpm-workspace.yaml in the global package directory for global installs.
Added support for pnpm config get globalconfig to retrieve the global config file path #9977.
Added a new setting virtualStoreOnly that populates the virtual store without creating importer symlinks, hoisting, bin links, or running lifecycle scripts. This is useful for pre-populating a store (e.g., in Nix builds) without creating unnecessary project-level artifacts. pnpm fetch now uses this mode internally #10840.
Added support for specifying the pnpm version via devEngines.packageManager in package.json. Unlike the packageManager field, this supports version ranges. The resolved version is stored in pnpm-lock.yaml and reused if it still satisfies the range #10932.
Added a new dedupePeers setting that reduces peer dependency duplication. When enabled, peer dependency suffixes use version-only identifiers (name@version) instead of full dep paths, eliminating nested suffixes like (foo@1.0.0(bar@2.0.0)). This dramatically reduces the number of package instances in projects with many recursive peer dependencies #11070.
Config dependencies are now installed into the global virtual store ({storeDir}/links/) and symlinked into node_modules/.pnpm-config/. This allows config dependencies to be shared across projects that use the same store, avoiding redundant fetches and imports #10910. Config dependency and package manager integrity info is now stored in pnpm-lock.yaml instead of inlined in pnpm-workspace.yaml: the workspace manifest contains only clean version specifiers for configDependencies, while the resolved versions, integrity hashes, and tarball URLs are recorded in the lockfile as a separate YAML document. The env lockfile section also stores packageManagerDependencies resolved during version switching and self-update. Projects using the old inline-hash format are automatically migrated on install #10912 #10964.
Added nodeDownloadMirrors setting to configure custom Node.js download mirrors in pnpm-workspace.yaml. This replaces the node-mirror:<channel> .npmrc setting, which is no longer read #11194:
nodeDownloadMirrors:
release: https://my-mirror.example.com/download/release/
pnpm dlx and pnpm create now respect security and trust policy settings (minimumReleaseAge, minimumReleaseAgeExclude, minimumReleaseAgeStrict, trustPolicy, trustPolicyExclude, trustPolicyIgnoreAfter) from project-level configuration #11183.
pnpm init now writes a devEngines.packageManager field instead of the packageManager field when init-package-manager is enabled.
Added a new setting runtimeOnFail that overrides the onFail field of devEngines.runtime (and engines.runtime) in the root project's package.json. Accepted values: ignore, warn, error, download. For example, setting runtimeOnFail=download makes pnpm download the declared runtime version even when the manifest does not set onFail: "download".
Added a new setting minimumReleaseAgeIgnoreMissingTime, which is true by default. When enabled, pnpm skips the minimumReleaseAge maturity check if the registry metadata does not include the time field. Set to false to fail resolution instead.
.mjs extension. When .pnpmfile.mjs exists, it takes priority over .pnpmfile.cjs and only one is loaded #9730.clean, setup, deploy, and rebuild commands now prefer user scripts over built-in commands. When a project's package.json has a script with the same name, pnpm executes the script instead of the built-in command. Added purge as an alias for the built-in clean command, which always runs the built-in regardless of scripts #11118.-F as a short alias for the --filter option.. are hidden and cannot be run directly via pnpm run. They can only be called from other scripts. Hidden scripts are also omitted from the pnpm run listing #11041.pnpm approve-builds now accepts positional arguments for approving or denying packages without the interactive prompt. Prefix a package name with ! to deny it. Only mentioned packages are affected; the rest are left untouched #11030.allowBuilds are automatically added to pnpm-workspace.yaml with a placeholder value, so users can manually set them to true or false #11030.pn and pnx short aliases for pnpm and pnpx (pnpm dlx) #11052.pnpm store prune now displays the total size of removed files #11047.pnpm audit --fix now adds the minimum patched version for each advisory to minimumReleaseAgeExclude in pnpm-workspace.yaml, so the security fix can be installed without waiting for minimumReleaseAge #11216.optimisticRepeatInstall skips shouldRefreshResolution hooks #10995.node-fetch with native undici for HTTP requests throughout pnpm #10537.node_modules, avoiding the overhead of creating a temp dir and renaming per package #11088.gunzipSync chunk size for fewer buffer allocations during tarball decompression #11086.If-Modified-Since for conditional metadata fetches, avoiding re-downloading unchanged registry metadata #11161.minimumReleaseAge, reducing the amount of data fetched from the registry #11160.Switched to process.stderr.write instead of console.error for script logging #11140.
Respected the frozen-lockfile flag when migrating config dependencies #11067.
Removed the --workspace flag from the version command #11115.
Handled ENOTSUP error in the clone import path during parallel I/O #11117.
Fixed pnpm audit command.
Updated dependencies to fix vulnerabilities.
pnpm now checks whether a package is installable for non-npm-hosted packages (e.g., git or tarball dependencies) after the manifest has been fetched.
pnpm now explicitly passes the path of the global rc config file to npm.
Fixed YAML formatting preservation in pnpm-workspace.yaml when running commands like pnpm update. Previously, quotes and other formatting were lost even when catalog values didn't change.
Closes #10425
The parameter set by the --allow-build flag is now written to allowBuilds.
Fixed a bug in which specifying filter in pnpm-workspace.yaml would cause pnpm to not detect any projects.
Deferred patch errors until all patches in a group are applied, so that one failed patch does not prevent other patches from being attempted.
pnpm now fails on incompatible lockfiles in CI when frozen lockfile mode is enabled #10978.
Fixed strictDepBuilds and allowBuilds checks being bypassed when a package's build side-effects are cached in the store #11039.
In GVS mode, pnpm approve-builds now runs a full install instead of rebuild, ensuring that GVS hash directories and symlinks are updated correctly after changing allowBuilds #11043.
Fixed a crash in the lockfile merger when merging non-semver version strings (e.g. link:, file:, git URLs) #11102.
Handled ENOTSUP error in linkOrCopy during parallel imports #11103.
Skipped linking bins that already reference the correct target. This avoids redundant I/O during repeated installs and prevents permission errors when the store is read-only (e.g. Docker layer caching, CI prewarm, NFS) #11069.
Fixed _password handling for the default registry to decode from base64 before use, consistent with scoped registry behavior #11089.
Fixed a bug where the CAS locker cache was not updated when a file already existed with correct integrity #11085.
Prevented catalog entries from being removed by cleanupUnusedCatalogs when they are referenced only from workspace overrides #11075.
Resolved patch file paths during pnpm fetch #11054.
Fixed invalid specifiers for peers on all non-exact version selectors #11049.
Fixed false "Command not found" error on Windows when the command exists but exits with a non-zero exit code #11000.
Prepended Bearer to the authorization token generated by tokenHelper if it is missing, aligning with npm's behavior #11097.
Propagated error cause when throwing PnpmError in @pnpm/npm-resolver #10990.
Fixed SQLite race condition during store initialization on Windows.
Removed rimrafSync in importIndexedDir fast-path error handler #11168.
Fixed pnpm dedupe --check unexpectedly failing due to non-deterministic resolution #11110.
Fixed empty files not being rejected in isEmptyDirOrNothing #11182.
Fixed .bat/.cmd token helpers not working on Windows due to missing shell: true option.
<!-- sponsors -->
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/sanity.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/sanity_light.svg" /> <img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" /> <img src="https://pnpm.io/img/users/discord.svg" width="220" alt="Discord" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/serpapi_dark.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/serpapi_light.svg" /> <img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160" alt="SerpApi" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" /> <img src="https://pnpm.io/img/users/coderabbit.svg" width="220" alt="CodeRabbit" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/stackblitz.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/stackblitz_light.svg" /> <img src="https://pnpm.io/img/users/stackblitz.svg" width="190" alt="Stackblitz" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/workleap.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/workleap_light.svg" /> <img src="https://pnpm.io/img/users/workleap.svg" width="190" alt="Workleap" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" /> <img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" /> </picture> </a> </td> </tr> </tbody> </table>
<!-- sponsors end -->
13e55b2: If install is performed on a subset of workspace projects, always create an up-to-date lockfile first. So, a partial install can be performed
Added a new command for printing the list of dependencies with ignored build scripts: pnpm ignored-builds #8963.
pnpm ignored-builds #8963.pnpm approve-builds #8963.optimistic-repeat-install. When enabled, a fast check will be performed before proceeding to installation. This way a repeat install or an install on a project with everything up-to-date becomes a lot faster. But some edge cases might arise, so we keep it disabled by default for now #8977.pnpm install, the preprepare and postprepare scripts of the project should be executed #8989.workspace: and catalog: to be part of wider version range in peerDependencies.pnpm deploy should inherit the pnpm object from the root package.json #8991.node_modules in a sub-project of a monorepo is detected as out-of-date #8959.pnpm to execute other scripts during pnpm install with verify-deps-before-run=install #8954.strip-ansi with the built-in util.stripVTControlCharacters #9009.<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a> </td> <td align="center" valign="middle"> <a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/sanity.svg" width="180" alt="Bit"></a> </td> <td align="center" valign="middle"> <a href="https://figma.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/figma.svg" width="80" alt="Figma"></a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" /> <img src="https://pnpm.io/img/users/discord.svg" width="220" alt="Discord" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/prisma.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/prisma_light.svg" /> <img src="https://pnpm.io/img/users/prisma.svg" width="180" alt="Prisma" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://uscreen.de/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/uscreen.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/uscreen_light.svg" /> <img src="https://pnpm.io/img/users/uscreen.svg" width="180" alt="u|screen" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://www.jetbrains.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/jetbrains.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/jetbrains.svg" /> <img src="https://pnpm.io/img/users/jetbrains.svg" width="180" alt="JetBrains" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" /> <img src="https://pnpm.io/img/users/nx.svg" width="120" alt="Nx" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" /> <img src="https://pnpm.io/img/users/coderabbit.svg" width="220" alt="CodeRabbit" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://route4me.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/route4me.svg" width="220" alt="Route4Me" /> </a> </td> <td align="center" valign="middle"> <a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/workleap.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/workleap_light.svg" /> <img src="https://pnpm.io/img/users/workleap.svg" width="190" alt="Workleap" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://canva.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/canva.svg" width="120" alt="Canva" /> </a> </td> </tr> </tbody> </table>
Lifecycle scripts of dependencies are not executed during installation by default! This is a breaking change aimed at increasing security. In order to…
Lifecycle scripts of dependencies are not executed during installation by default! This is a breaking change aimed at increasing security. In order to allow lifecycle scripts of specific dependencies, they should be listed in the pnpm.onlyBuiltDependencies field of package.json #8897. For example:
{
"pnpm": {
"onlyBuiltDependencies": ["fsevents"]
}
}
Read pnpm 10.0.0 Blocks Lifecycle Scripts by Default to learn about the motivation of the change.
If you want the old pre v10 behaviour, so you want to allow all dependencies to run postinstall scripts, then add this to your package.json:
{
"pnpm": {
"neverBuiltDependencies": []
}
}
pnpm link behavior updated:
The pnpm link command now adds overrides to the root package.json.
pnpm link from the package’s directory. Previously, you needed to use pnpm link -g.
Related PR: #8653Secure hashing with SHA256:
Various hashing algorithms have been updated to SHA256 for enhanced security and consistency:
node_modules/.pnpm are now hashed with SHA256.packageExtensionsChecksum field of pnpm-lock.yaml is now SHA256.Configuration updates:
manage-package-manager-versions: enabled by default. pnpm now manages its own version based on the packageManager field in package.json by default.
public-hoist-pattern: nothing is hoisted by default. Packages containing eslint or prettier in their name are no longer hoisted to the root of node_modules. Related Issue: #8378
Upgraded @yarnpkg/extensions to v2.0.3. This may alter your lockfile.
virtual-store-dir-max-length: the default value on Windows has been reduced to 60 characters.
Reduced environment variables for scripts:
During script execution, fewer npm_package_* environment variables are set. Only name, version, bin, engines, and config remain.
Related Issue: #8552
All dependencies are now installed even if NODE_ENV=production. Related Issue: #8827
Changes to the global store:
Store version bumped to v10.
Some registries allow identical content to be published under different package names or versions. To accommodate this, index files in the store are now stored using both the content hash and package identifier.
This approach ensures that we can:
More efficient side effects indexing. The structure of index files in the store has changed. Side effects are now tracked more efficiently by listing only file differences rather than all files. Related PR: #8636
A new index directory stores package content mappings. Previously, these files were in files.
Other breaking changes:
# character is now escaped in directory names within node_modules/.pnpm.
Related PR: #8557pnpm add --global pnpm or pnpm add --global @pnpm/exe now fails with an error message, directing you to use pnpm self-update instead.
Related PR: #8728pnpm deploy command now only works in workspaces that have inject-workspace-packages=true. This limitation is introduced to allow us to create a proper lockfile for the deployed project using the workspace lockfile.pnpm test now passes all parameters after the test keyword directly to the underlying script. This matches the behavior of pnpm run test. Previously you needed to use the -- prefix.
Related PR: #8619node-gyp updated to version 11.
pnpm deploy now tries creating a dedicated lockfile from a shared lockfile for deployment. It will fallback to deployment without a lockfile if there is no shared lockfile or force-legacy-deploy is set to true.
Added support for a new type of dependencies called "config dependencies". These dependencies are installed before all the other types of dependencies (before "dependencies", "devDependencies", "optionalDependencies").
Config dependencies cannot have dependencies of their own or lifecycle scripts. They should be added using exact version and the integrity checksum. Example:
{
"pnpm": {
"configDependencies": {
"my-configs": "1.0.0+sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="
}
}
}
New settings:
New verify-deps-before-run setting. This setting controls how pnpm checks node_modules before running scripts:
install: Automatically run pnpm install if node_modules is outdated.warn: Print a warning if node_modules is outdated.prompt: Prompt the user to confirm running pnpm install if node_modules is outdated.error: Throw an error if node_modules is outdated.false: Disable dependency checks.
Related Issue: #8585New inject-workspace-packages setting enables hard-linking all local workspace dependencies instead of symlinking them. Previously, this could be achieved using dependenciesMeta[].injected, which remains supported.
Related PR: #8836
Faster repeat installs:
On repeated installs, pnpm performs a quick check to ensure node_modules is up to date.
Related PR: #8838
pnpm add integrates with default workspace catalog:
When adding a dependency, pnpm add checks the default workspace catalog. If the dependency and version requirement match the catalog, pnpm add uses the catalog: protocol. Without a specified version, it matches the catalog’s version. If it doesn’t match, it falls back to standard behavior.
Related Issue: #8640
pnpm dlx now resolves packages to their exact versions and uses these exact versions for cache keys. This ensures pnpm dlx always installs the latest requested packages.
Related PR: #8811
No node_modules validation on certain commands. Commands that should not modify node_modules (e.g., pnpm install --lockfile-only) no longer validate or purge node_modules.
Related PR: #8657
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a> </td> <td align="center" valign="middle"> <a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/sanity.svg" width="180" alt="Bit"></a> </td> <td align="center" valign="middle"> <a href="https://figma.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/figma.svg" width="80" alt="Figma"></a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" /> <img src="https://pnpm.io/img/users/discord.svg" width="220" alt="Discord" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/prisma.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/prisma_light.svg" /> <img src="https://pnpm.io/img/users/prisma.svg" width="180" alt="Prisma" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://uscreen.de/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/uscreen.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/uscreen_light.svg" /> <img src="https://pnpm.io/img/users/uscreen.svg" width="180" alt="u|screen" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://www.jetbrains.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/jetbrains.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/jetbrains.svg" /> <img src="https://pnpm.io/img/users/jetbrains.svg" width="180" alt="JetBrains" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" /> <img src="https://pnpm.io/img/users/nx.svg" width="120" alt="Nx" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" /> <img src="https://pnpm.io/img/users/coderabbit.svg" width="220" alt="CodeRabbit" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://route4me.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/route4me.svg" width="220" alt="Route4Me" /> </a> </td> <td align="center" valign="middle"> <a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/workleap.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/workleap_light.svg" /> <img src="https://pnpm.io/img/users/workleap.svg" width="190" alt="Workleap" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://canva.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/canva.svg" width="120" alt="Canva" /> </a> </td> </tr> </tbody> </table>
7733f3a: Added support for registry-scoped SSL configurations (cert, key, and ca). Three new settings supported: <registryURL>:certfile, <registryURL>:keyfile, and <registryURL>:ca. For instance:
//registry.mycomp.com/:certfile=server-cert.pem
//registry.mycomp.com/:keyfile=server-key.pem
//registry.mycomp.com/:cafile=client-cert.pem
730929e: Add a field named ignoredOptionalDependencies. This is an array of strings. If an optional dependency has its name included in this array, it will be skipped.
4d34684f1: Added support for boolean values in 'bundleDependencies' package.json fields when installing a dependency. Fix to properly handle 'bundledD
Added support for boolean values in 'bundleDependencies' package.json fields when installing a dependency. Fix to properly handle 'bundledDependencies
Some registries allow the exact same content to be published under different package names and/or versions. This breaks the validity checks of package
strict-store-pkg-content-check setting to false #4724.package-manager-strict-version missing in config #8195.<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80"></a> </td> <td align="center" valign="middle"> <a href="https://figma.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/figma.svg" width="80"></a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" /> <img src="https://pnpm.io/img/users/discord.svg" width="220" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/prisma.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/prisma_light.svg" /> <img src="https://pnpm.io/img/users/prisma.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://uscreen.de/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/uscreen.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/uscreen_light.svg" /> <img src="https://pnpm.io/img/users/uscreen.svg" width="180" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://www.jetbrains.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/jetbrains.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/jetbrains.svg" /> <img src="https://pnpm.io/img/users/jetbrains.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" /> <img src="https://pnpm.io/img/users/nx.svg" width="120" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" /> <img src="https://pnpm.io/img/users/coderabbit.svg" width="220" /> </picture> </a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/leniolabs.jpg" width="80"> </a> </td> <td align="center" valign="middle"> <a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/vercel.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/vercel_light.svg" /> <img src="https://pnpm.io/img/users/vercel.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://depot.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/depot.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/depot_light.svg" /> <img src="https://pnpm.io/img/users/depot.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://moonrepo.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/moonrepo.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/moonrepo_light.svg" /> <img src="https://pnpm.io/img/users/moonrepo.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://devowl.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <img src="https://pnpm.io/img/users/devowlio.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://macpaw.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/macpaw.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/macpaw_light.svg" /> <img src="https://pnpm.io/img/users/macpaw.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://cerbos.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/cerbos.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/cerbos_light.svg" /> <img src="https://pnpm.io/img/users/cerbos.svg" width="180" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://vpsserver.com/en-us/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/vpsserver.svg" width="180" /> </a> </td> </tr> </tbody> </table>
43ce9e4a6: Support for multiple architectures when installing dependencies #5965.
You can now 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. Use the supportedArchitectures field in package.json to define your preferences.
For example, the following configuration tells pnpm to install optional dependencies for Windows x64:
{
"pnpm": {
"supportedArchitectures": {
"os": ["win32"],
"cpu": ["x64"]
}
}
}
Whereas this configuration will have pnpm 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:
{
"pnpm": {
"supportedArchitectures": {
"os": ["win32", "darwin", "current"],
"cpu": ["x64", "arm64"]
}
}
}
Additionally, supportedArchitectures also supports specifying the libc of the system.
Semi-breaking. Dependency key names in the lockfile are shortened if they are longer than 1000 characters. We don't expect this change to affect many
peers-suffix-max-length setting #8177.reporter-hide-prefix to true by default for pnpm exec. In order to show prefix, the user now has to explicitly set reporter-hide-prefix=false #8174.<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80"></a> </td> <td align="center" valign="middle"> <a href="https://figma.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/figma.svg" width="80"></a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" /> <img src="https://pnpm.io/img/users/discord.svg" width="220" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/prisma.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/prisma_light.svg" /> <img src="https://pnpm.io/img/users/prisma.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://uscreen.de/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/uscreen.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/uscreen_light.svg" /> <img src="https://pnpm.io/img/users/uscreen.svg" width="180" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://www.jetbrains.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/jetbrains.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/jetbrains.svg" /> <img src="https://pnpm.io/img/users/jetbrains.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" /> <img src="https://pnpm.io/img/users/nx.svg" width="120" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" /> <img src="https://pnpm.io/img/users/coderabbit.svg" width="220" /> </picture> </a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/leniolabs.jpg" width="80"> </a> </td> <td align="center" valign="middle"> <a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/vercel.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/vercel_light.svg" /> <img src="https://pnpm.io/img/users/vercel.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://depot.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/depot.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/depot_light.svg" /> <img src="https://pnpm.io/img/users/depot.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://moonrepo.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/moonrepo.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/moonrepo_light.svg" /> <img src="https://pnpm.io/img/users/moonrepo.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://devowl.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <img src="https://pnpm.io/img/users/devowlio.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://macpaw.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/macpaw.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/macpaw_light.svg" /> <img src="https://pnpm.io/img/users/macpaw.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://cerbos.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/cerbos.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/cerbos_light.svg" /> <img src="https://pnpm.io/img/users/cerbos.svg" width="180" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://vpsserver.com/en-us/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/vpsserver.svg" width="180" /> </a> </td> </tr> </tbody> </table>
d774a3196: The list of packages that are allowed to run installation scripts now may be provided in a separate configuration file. The path to the file should be specified via the pnpm.onlyBuiltDependenciesFile field in package.json. For instance:
{
"dependencies": {
"@my-org/policy": "1.0.0"
}
"pnpm": {
"onlyBuiltDependenciesFile": "node_modules/@my-org/policy/allow-build.json"
}
}
In the example above, the list is loaded from a dependency. The JSON file with the list should contain an array of package names. For instance:
["esbuild", "@reflink/reflink"]
With the above list, only esbuild and @reflink/reflink will be allowed to run scripts during installation.
Related issue: #7137.
If package-manager-strict-version is set to true, pnpm will fail if its version doesn't exactly match the version in the "packageManager" field of pac
package-manager-strict-version is set to true, pnpm will fail if its version doesn't exactly match the version in the "packageManager" field of package.json.@yarnpkg/pnp to the latest version, fixing issue with node: imports #8161.package.json #8087.exec now also streams prefixed output when --recursive or --parallel is specified just as run does #8065.<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80"></a> </td> <td align="center" valign="middle"> <a href="https://figma.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/figma.svg" width="80"></a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" /> <img src="https://pnpm.io/img/users/discord.svg" width="220" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/prisma.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/prisma_light.svg" /> <img src="https://pnpm.io/img/users/prisma.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://uscreen.de/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/uscreen.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/uscreen_light.svg" /> <img src="https://pnpm.io/img/users/uscreen.svg" width="180" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://www.jetbrains.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/jetbrains.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/jetbrains.svg" /> <img src="https://pnpm.io/img/users/jetbrains.svg" width="85" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" /> <img src="https://pnpm.io/img/users/nx.svg" width="120" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" /> <img src="https://pnpm.io/img/users/coderabbit.svg" width="220" /> </picture> </a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/leniolabs.jpg" width="80"> </a> </td> <td align="center" valign="middle"> <a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/vercel.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/vercel_light.svg" /> <img src="https://pnpm.io/img/users/vercel.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://depot.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/depot.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/depot_light.svg" /> <img src="https://pnpm.io/img/users/depot.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://moonrepo.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/moonrepo.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/moonrepo_light.svg" /> <img src="https://pnpm.io/img/users/moonrepo.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://devowl.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <img src="https://pnpm.io/img/users/devowlio.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://macpaw.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/macpaw.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/macpaw_light.svg" /> <img src="https://pnpm.io/img/users/macpaw.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://cerbos.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/cerbos.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/cerbos_light.svg" /> <img src="https://pnpm.io/img/users/cerbos.svg" width="180" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://vpsserver.com/en-us/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/vpsserver.svg" width="180" /> </a> </td> </tr> </tbody> </table>
publishConfig.registry in package.json for publishing #6775.New setting called virtual-store-dir-max-length added to modify the maximum allowed length of the directories inside node_modules/.pnpm. The default l
virtual-store-dir-max-length added to modify the maximum allowed length of the directories inside node_modules/.pnpm. The default length is set to 120 characters. This setting is particularly useful on Windows, where there is a limit to the maximum length of a file path #7355.pnpm outdated output are wrapped correctly #8037.Cannot read properties of undefined (reading 'missingPeersOfChildren') exception that happens on install #8041.publish or pack when bundledDependencies is set but node-linker isn't hoisted.pnpm update should not fail when there's an aliased local workspace dependency #7975.<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80"></a> </td> <td align="center" valign="middle"> <a href="https://figma.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/figma.svg" width="80"></a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" /> <img src="https://pnpm.io/img/users/discord.svg" width="220" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/prisma.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/prisma_light.svg" /> <img src="https://pnpm.io/img/users/prisma.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://uscreen.de/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/uscreen.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/uscreen_light.svg" /> <img src="https://pnpm.io/img/users/uscreen.svg" width="180" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://www.jetbrains.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/jetbrains.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/jetbrains.svg" /> <img src="https://pnpm.io/img/users/jetbrains.svg" width="85" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" /> <img src="https://pnpm.io/img/users/nx.svg" width="120" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" /> <img src="https://pnpm.io/img/users/coderabbit.svg" width="220" /> </picture> </a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/leniolabs.jpg" width="80"> </a> </td> <td align="center" valign="middle"> <a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/vercel.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/vercel_light.svg" /> <img src="https://pnpm.io/img/users/vercel.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://depot.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/depot.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/depot_light.svg" /> <img src="https://pnpm.io/img/users/depot.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://moonrepo.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/moonrepo.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/moonrepo_light.svg" /> <img src="https://pnpm.io/img/users/moonrepo.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://devowl.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <img src="https://pnpm.io/img/users/devowlio.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://macpaw.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/macpaw.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/macpaw_light.svg" /> <img src="https://pnpm.io/img/users/macpaw.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://cerbos.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/cerbos.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/cerbos_light.svg" /> <img src="https://pnpm.io/img/users/cerbos.svg" width="180" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://vpsserver.com/en-us/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/vpsserver.svg" width="180" /> </a> </td> </tr> </tbody> </table>
Node.js v16 and 17 support discontinued
Node.js v16 and 17 support discontinued
If you still require Node.js 16 or 17, don't worry. We ship pnpm bundled with Node.js. This means that regardless of which Node.js version you've installed, pnpm will operate using the necessary Node.js runtime. For this to work you need to install pnpm either using the standalone script or install the @pnpm/exe package.
Corepack compatiblity:
pnpm will now check the package.json file for a packageManager field. If this field is present and specifies a different package manager or a different version of pnpm than the one you're currently using, pnpm will not proceed. This ensures that you're always using the correct package manager and version that the project requires.
NOTE: If you want to make this check less strict, set the package-manager-strict setting to false or the COREPACK_ENABLE_STRICT env variable to 0.
Configuration updates:
dedupe-injected-deps: enabled by default.link-workspace-packages: disabled by default. This means that by default, dependencies will be linked from workspace packages only when they are specified using the workspace protocol.hoist-workspace-packages: enabled by default.enable-pre-post-scripts: enabled by default.~/.local/state/pnpm).Lockfile changes:
Dependency resolution changes:
pnpm licenses list prints license information of all versions of the same package in case different versions use different licenses. The format of the pnpm licenses list --json output has been changed #7528.
A new command added for printing completion code to the console: pnpm completion [shell]. The old command that modified the user's shell dotfiles has been removed #3083.
When installing git-hosted dependencies, only pick the files that would be packed with the package #7638.
It is now possible to install only a subdirectory from a Git repository.
For example, pnpm add github:user/repo#path:packages/foo will add a dependency from the packages/foo subdirectory.
This new parameter may be combined with other supported parameters separated by &. For instance, the next command will install the same package from the dev branch: pnpm add github:user/repo#dev&path:packages/bar.
node-gyp updated to version 10.
PowerShell completion support added #7597.
Support node-options option inside .npmrc file when running scripts #7596.
Added support for registry-scoped SSL configurations (cert, key, and ca). Three new settings supported: <registryURL>:certfile, <registryURL>:keyfile, and <registryURL>:ca. For instance:
//registry.mycomp.com/:certfile=server-cert.pem
//registry.mycomp.com/:keyfile=server-key.pem
//registry.mycomp.com/:cafile=client-cert.pem
Add a field named ignoredOptionalDependencies. This is an array of strings. If an optional dependency has its name included in this array, it will be skipped #7714.
The checksum of the .pnpmfile.cjs is saved into the lockfile. If the pnpmfile gets modified, the lockfile is reanalyzed to apply the changes #7662.
Added cache for pnpm dlx #5277.
--lockfile-only installation #1328.pnpm dlx should not read settings from the current working directory #7916.<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80"></a> </td> <td align="center" valign="middle"> <a href="https://figma.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/figma.svg" width="80"></a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" /> <img src="https://pnpm.io/img/users/discord.svg" width="220" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/prisma.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/prisma_light.svg" /> <img src="https://pnpm.io/img/users/prisma.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://uscreen.de/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/uscreen.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/uscreen_light.svg" /> <img src="https://pnpm.io/img/users/uscreen.svg" width="180" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://www.jetbrains.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/jetbrains.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/jetbrains.svg" /> <img src="https://pnpm.io/img/users/jetbrains.svg" width="85" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" /> <img src="https://pnpm.io/img/users/nx.svg" width="120" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" /> <img src="https://pnpm.io/img/users/coderabbit.svg" width="220" /> </picture> </a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/leniolabs.jpg" width="80"> </a> </td> <td align="center" valign="middle"> <a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/vercel.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/vercel_light.svg" /> <img src="https://pnpm.io/img/users/vercel.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://depot.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/depot.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/depot_light.svg" /> <img src="https://pnpm.io/img/users/depot.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://moonrepo.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/moonrepo.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/moonrepo_light.svg" /> <img src="https://pnpm.io/img/users/moonrepo.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://devowl.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <img src="https://pnpm.io/img/users/devowlio.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://macpaw.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/macpaw.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/macpaw_light.svg" /> <img src="https://pnpm.io/img/users/macpaw.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://cerbos.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/cerbos.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/cerbos_light.svg" /> <img src="https://pnpm.io/img/users/cerbos.svg" width="180" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://vpsserver.com/en-us/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/vpsserver.svg" width="180" /> </a> </td> </tr> </tbody> </table>
Support for multiple architectures when installing dependencies #5965.
Support for multiple architectures when installing dependencies #5965.
You can now 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. Use the supportedArchitectures field in package.json to define your preferences.
For example, the following configuration tells pnpm to install optional dependencies for Windows x64:
{
"pnpm": {
"supportedArchitectures": {
"os": ["win32"],
"cpu": ["x64"]
}
}
}
Whereas this configuration will have pnpm 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:
{
"pnpm": {
"supportedArchitectures": {
"os": ["win32", "darwin", "current"],
"cpu": ["x64", "arm64"]
}
}
}
Additionally, supportedArchitectures also supports specifying the libc of the system.
The pnpm licenses list command now accepts the --filter option to check the licenses of the dependencies of a subset of workspace projects #5806.
Allow scoped name as bin name #7112.
When running scripts recursively inside a workspace, the logs of the scripts are grouped together in some CI tools. (Only works with --workspace-concurrency 1)
Print a warning when installing a dependency from a non-existent directory #7159
Should fetch dependency from tarball url when patching dependency installed from git #7196
pnpm setup should add a newline at the end of the updated shell config file #7227.
Improved the performance of linking bins of hoisted dependencies to node_modules/.pnpm/node_modules/.bin #7212.
Wrongful ELIFECYCLE error on program termination #7164.
pnpm publish should not pack the same file twice sometimes #6997.
The fix was to update npm-packlist to the latest version.
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80"></a> </td> <td align="center" valign="middle"> <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/prisma.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/prisma_light.svg" /> <img src="https://pnpm.io/img/users/prisma.svg" width="180" /> </picture> </a> </td> <tr> <td align="center" valign="middle"> <a href="https://uscreen.de/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/uscreen.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/uscreen_light.svg" /> <img src="https://pnpm.io/img/users/uscreen.svg" width="180" /> </picture> </a> </td> </tr> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/leniolabs.jpg" width="80"> </a> </td> <td align="center" valign="middle"> <a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/vercel.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/vercel_light.svg" /> <img src="https://pnpm.io/img/users/vercel.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://depot.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/depot.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/depot_light.svg" /> <img src="https://pnpm.io/img/users/depot.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://moonrepo.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/moonrepo.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/moonrepo_light.svg" /> <img src="https://pnpm.io/img/users/moonrepo.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://www.thinkmill.com.au/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/thinkmill.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/thinkmill_light.svg" /> <img src="https://pnpm.io/img/users/thinkmill.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://devowl.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <img src="https://pnpm.io/img/users/devowlio.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://macpaw.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/macpaw.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/macpaw_light.svg" /> <img src="https://pnpm.io/img/users/thinkmill.svg" width="200" /> </picture> </a> </td> </tr> </tbody> </table>
package.json that is in the root of the workspace: pnpm.requiredScripts. Scripts listed in this array will be required in each project of the workspace. Otherwise, pnpm -r run <script name> will fail #5569.🚀Performance improvement: Use reflinks instead of hard links by default on macOS and Windows Dev Drives #5001.
🚀Performance improvement: Use reflinks instead of hard links by default on macOS and Windows Dev Drives #5001.
The list of packages that are allowed to run installation scripts now may be provided in a separate configuration file. The path to the file should be specified via the pnpm.onlyBuiltDependenciesFile field in package.json. For instance:
{
"dependencies": {
"@my-org/policy": "1.0.0"
}
"pnpm": {
"onlyBuiltDependenciesFile": "node_modules/@my-org/policy/allow-build.json"
}
}
In the example above, the list is loaded from a dependency. The JSON file with the list should contain an array of package names. For instance:
["esbuild", "@reflink/reflink"]
With the above list, only esbuild and @reflink/reflink will be allowed to run scripts during installation.
Related issue: #7137.
Add disallow-workspace-cycles option to error instead of warn about cyclic dependencies
Allow env rm to remove multiple node versions at once, and introduce env add for installing node versions without setting as default #7155.
pnpm why when the dependencies tree is too big, the command will now prune the tree to just 10 end leafs and now supports --depth argument #7122.neverBuiltDependencies and onlyBuiltDependencies from the root package.json of the workspace, when shared-workspace-lockfile is set to false #7141.pnpm.overrides replacing resolutions, the two are now merged. This is intended to make it easier to migrate from Yarn by allowing one to keep using resolutions for Yarn, but adding additional changes just for pnpm using pnpm.overrides.<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80"></a> </td> <td align="center" valign="middle"> <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/prisma.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/prisma_light.svg" /> <img src="https://pnpm.io/img/users/prisma.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://uscreen.de/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/uscreen.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/uscreen_light.svg" /> <img src="https://pnpm.io/img/users/uscreen.svg" width="180" /> </picture> </a> </td> </tr>
</tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/leniolabs.jpg" width="80"> </a> </td> <td align="center" valign="middle"> <a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/vercel.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/vercel_light.svg" /> <img src="https://pnpm.io/img/users/vercel.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://depot.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/depot.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/depot_light.svg" /> <img src="https://pnpm.io/img/users/depot.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://moonrepo.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/moonrepo.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/moonrepo_light.svg" /> <img src="https://pnpm.io/img/users/moonrepo.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://www.thinkmill.com.au/?utm_source=pnpm&utm_medium=readme" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/thinkmill.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/thinkmill_light.svg" /> <img src="https://pnpm.io/img/users/thinkmill.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://devowl.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <img src="https://pnpm.io/img/users/devowlio.svg" width="200" /> </picture> </a> </td> </tr> </tbody> </table>
702e847c1: A new setting supported for ignoring vulnerabilities by their CVEs. The ignored CVEs may be listed in the pnpm.auditConfig.ignoreCves field of package.json. For instance:
{
"pnpm": {
"auditConfig": {
"ignoreCves": [
"CVE-2019-10742",
"CVE-2020-28168",
"CVE-2021-3749",
"CVE-2020-7598"
]
}
}
}
Add --reporter-hide-prefix option for run command to hide project name as prefix for lifecycle log outputs of running scripts #7061.
--reporter-hide-prefix option for run command to hide project name as prefix for lifecycle log outputs of running scripts #7061.--ignore-scripts command to install, when running pnpm dedupe --ignore-scripts #7102.node-linker is set to hoisted, the package.json files of the existing dependencies inside node_modules will be checked to verify their actual versions. The data in the node_modules/.modules.yaml and node_modules/.pnpm/lock.yaml may not be fully reliable, as an installation may fail after changes to dependencies were made but before those state files were updated #7107.<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80"></a> </td> <td align="center" valign="middle"> <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/prisma.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/prisma_light.svg" /> <img src="https://pnpm.io/img/users/prisma.svg" width="180" /> </picture> </a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/leniolabs.jpg" width="80"> </a> </td> <td align="center" valign="middle"> <a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/vercel.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/vercel_light.svg" /> <img src="https://pnpm.io/img/users/vercel.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://depot.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/depot.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/depot_light.svg" /> <img src="https://pnpm.io/img/users/depot.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://moonrepo.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/moonrepo.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/moonrepo_light.svg" /> <img src="https://pnpm.io/img/users/moonrepo.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://www.thinkmill.com.au/?utm_source=pnpm&utm_medium=readme" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/thinkmill.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/thinkmill_light.svg" /> <img src="https://pnpm.io/img/users/thinkmill.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://devowl.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <img src="https://pnpm.io/img/users/devowlio.svg" width="200" /> </picture> </a> </td> </tr> </tbody> </table>
…set to highest by default). This is a semi-breaking change but should not affect users that commit their lockfile #6463.
resolution-mode setting is changed to highest. This setting was changed to lowest-direct in v8.0.0 and some users were not happy with the change. A twitter poll concluded that most of the users want the old behaviour (resolution-mode set to highest by default). This is a semi-breaking change but should not affect users that commit their lockfile #6463.peerDependencies #615.pnpm import #6233.peerDependencies in pnpm.overrides #6759.pnpm patch should write patch files with a trailing newline #6905.<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80"></a> </td> <td align="center" valign="middle"> <a href="https://novu.co/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/novu.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/novu_light.svg" /> <img src="https://pnpm.io/img/users/novu.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/prisma.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/prisma_light.svg" /> <img src="https://pnpm.io/img/users/prisma.svg" width="180" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://www.flightcontrol.dev/?ref=pnpm" target="_blank"><img src="https://pnpm.io/img/users/flightcontrol.svg" width="240"></a> </td> </tr> </tbody> </table>
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <img src="https://pnpm.io/img/users/leniolabs.jpg" width="80"> </a> </td> <td align="center" valign="middle"> <a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/vercel.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/vercel_light.svg" /> <img src="https://pnpm.io/img/users/vercel.svg" width="180" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://depot.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/depot.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/depot_light.svg" /> <img src="https://pnpm.io/img/users/depot.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://moonrepo.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/moonrepo.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/moonrepo_light.svg" /> <img src="https://pnpm.io/img/users/moonrepo.svg" width="200" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://www.thinkmill.com.au/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/thinkmill.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/thinkmill_light.svg" /> <img src="https://pnpm.io/img/users/thinkmill.svg" width="200" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://devowl.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/devowlio.svg" /> <img src="https://pnpm.io/img/users/devowlio.svg" width="200" /> </picture> </a> </td> </tr> </tbody> </table>
156cc1ef6: A new setting supported in the pnpm section of the package.json file: allowNonAppliedPatches. When it is set to true, non-applied patches w
156cc1ef6: A new setting supported in the pnpm section of the package.json file: allowNonAppliedPatches. When it is set to true, non-applied patches will not cause an error, just a warning will be printed. For example:
{
"name": "foo",
"version": "1.0.0",
"pnpm": {
"patchedDependencies": {
"express@4.18.1": "patches/express@4.18.1.patch"
},
"allowNonAppliedPatches": true
}
}
c90798461: When publishConfig.directory is set, only symlink it to other workspace projects if publishConfig.linkDirectory is set to true. Otherwise,
publishConfig.directory is set, only symlink it to other workspace projects if publishConfig.linkDirectory is set to true. Otherwise, only use it for publishing #5115.### Minor Changes - 8e5b77ef6: Add PatchFile type.
2a34b21ce: Dependencies patching is possible via the pnpm.patchedDependencies field of the package.json. To patch a package, the package name, exact v
2a34b21ce: Dependencies patching is possible via the pnpm.patchedDependencies field of the package.json.
To patch a package, the package name, exact version, and the relative path to the patch file should be specified. For instance:
{
"pnpm": {
"patchedDependencies": {
"eslint@1.0.0": "./patches/eslint@1.0.0.patch"
}
}
}
fb5bbfd7a: A new setting added: pnpm.peerDependencyRules.allowAny. allowAny is an array of package name patterns, any peer dependency matching the pat
fb5bbfd7a: A new setting added: pnpm.peerDependencyRules.allowAny. allowAny is an array of package name patterns, any peer dependency matching the pattern will be resolved from any version, regardless of the range specified in peerDependencies. For instance:
{
"pnpm": {
"peerDependencyRules": {
"allowAny": ["@babel/*", "eslint"]
}
}
}
The above setting will mute any warnings about peer dependency version mismatches related to @babel/ packages or eslint.
Your coding agent can read these notes before it upgrades. Set up the MCP server →