chore(deps): update pnpm to v12.0.0 - #879
Merged
Merged
Conversation
commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #879 +/- ##
=======================================
Coverage 94.24% 94.24%
=======================================
Files 10 10
Lines 747 747
Branches 235 235
=======================================
Hits 704 704
Misses 40 40
Partials 3 3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
renovate
Bot
force-pushed
the
renovate/pnpm-12.x
branch
2 times, most recently
from
August 27, 2026 21:38
cac24e9 to
0b2c029
Compare
renovate
Bot
force-pushed
the
renovate/pnpm-12.x
branch
from
August 28, 2026 03:26
0b2c029 to
0b91312
Compare
renovate
Bot
force-pushed
the
renovate/pnpm-12.x
branch
from
August 29, 2026 17:40
0b91312 to
5980e29
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
12.0.0-rc.8→12.0.0Release Notes
pnpm/pnpm (pnpm)
v12.0.0: pnpm 12Compare Source
Major Changes
Git dependencies on known hosts (GitHub, GitLab, Bitbucket) are now treated as identities rather than transport choices. Every representation of the same repository —
github:owner/repo,owner/repo,git+https://…,git+ssh://git@…— resolves through the host's canonical HTTPS URL, and the lockfile never records an SSH URL for them. Repositories whose archive endpoint is anonymously reachable resolve to the host's archive (fast tarball download); all others resolve to agitclone of the canonical HTTPS URL, which every machine with access to the repository can fetch.To reach a private hosted repository over SSH, configure the machine (not the project) with git's own URL rewriting, for example:
git config --global url."git@github.com:".insteadOf https://github.com/pnpm shells out to
git, so the rewrite applies to all of pnpm's git operations automatically. URLs of unknown hosts (self-hosted servers) are unaffected and keep their exact URL, including SSH. URLs with embedded credentials are also kept verbatim and never resolve to a host archive.This removes the network probing that previously decided between HTTPS and SSH at resolution time, which could record a transport that only worked on the machine that happened to run the resolution (e.g. an SSH URL that broke CI runners without SSH keys).
A project's
pnpm-workspace.yamlmay no longer carry a setting pnpm does not recognize. Such a setting used to be ignored in silence — a misspelledminimumReleaseAgedropped the policy it was meant to set, and nothing said so. Now it is reported, suggesting the closest real setting name when the key looks like a typo, and it fails the command withERR_PNPM_UNRECOGNIZED_WORKSPACE_SETTINGSwhen the project pins a pnpm version the running pnpm satisfies: with the pin honored, the setting cannot be meant for a different pnpm version, so it is a mistake to fix rather than a key to ignore. Everywhere else it is a warning, so a project that has yet to be cleaned up keeps working.The
pnpm configsubcommands never fail on such a setting, so a broken file can still be inspected and repaired, andpnpm config get <key>prints the value with no warnings at all. Keys the global config file cannot set are likewise split between workspace-only settings (still directed topnpm-workspace.yaml) and settings unknown to this version.Dependency cycles are now broken canonically during peer resolution: the members of each cycle are ordered by package id, and the edges that close a cycle are always cut at the same place, no matter where the installation walks into the cycle from. Previously the cut depended on the walk path, so installing the same dependencies could produce different lockfiles depending on importer order or resolution order #13846, and a peer-resolution verdict computed for one occurrence of a cyclic package could be wrongly reused at another #13865.
With canonical cycle breaking the lockfile is a pure function of the dependency graph: repeated installs, reordered importers, and reordered dependencies all produce byte-identical lockfiles. Peer dependencies of packages inside a cycle keep nearest-wins resolution along the canonical order, and a dependency edge that closes a cycle references an occurrence of its target resolved at the importer level. On large cycle-heavy workspaces peer resolution is 2–3× faster, uses about 25% less memory, and produces a substantially smaller lockfile (fewer redundant peer variants).
Existing lockfiles keep working: headless (
--frozen-lockfile) installs consume them unchanged, and installs that skip resolution leave them untouched. The first install that actually re-resolves (for example after a dependency change) re-keys walk-order-dependent peer variants of cyclic packages once.packageImportMethod: autonow tries hardlinks before cloning on Linux. A reflink materializes a new inode and copies extent bookkeeping inside the filesystem's metadata trees, where a hardlink is one directory entry — on btrfs this roughly halves the time an install spends materializingnode_modulesfrom a warm store. ext4 installs are unchanged (cloning was never supported there, soautoalready hardlinked), and macOS keeps clone-first, where APFSclonefileis the platform's cheap primitive. Cloning remains the fallback when the store refuses hardlinks, and remains available explicitly viapackageImportMethod: clone.Under
engineStrict, an install fails when an incompatible package is reached through a regulardependenciesedge of an installable package, even when that whole subtree hangs off anoptionalDependenciesentry. pnpm v11 installs the package and emits an install-check warning instead. Packages reachable only through optional edges, or through a package that was itself skipped, are still skipped in both versions #13286.Minor Changes
Globally installed bins can now follow the project you run them in. The new
globalShimssetting is a record of package names to policies that selects which globally installed packages get project-aware shims; it defaults to{ node: true, deno: true, bun: true }and merges key-wise, soglobalShims: { bun: false }switches one default off andglobalShims: { typescript: true }adds another package. With the default, a project that pins Node.js throughdevEngines.runtimeorengines.runtimegets the pinned stable release — authenticated against the Node.js release-team signatures — downloaded on first use and run whenever you typenodeinside the project, with no shell hooks. Candidates that are not signature-verified (Deno, Bun, Node.js prereleases, and ordinary package bins you enable) ask "Do you trust this project?" once per candidate and remember the answer machine-locally; the record values name the policy per package:"auto"(or its shorthandtrue) defers to artifact authentication,"always"switches without ever asking (useful in CI), and"prompt"always asks, even for authenticated candidates. SetglobalShims: falseto disable the feature, orPNPM_SHIM_BYPASS=1to bypass it for one invocation. On Windows, programs can keep spawning the globalnode.exedirectly, without a shell.pnpm installs the other package managers now, not just itself: npm, Yarn Classic, Yarn Berry, Yarn 6 (
yarnpkg/zpm), and Bun. Each is resolved and fetched through the trusted package-manager registries, and an npm-published one is verified against npm's signature for its exact version before it is executed.Three things use it:
packageManager/devEngines.packageManagerpin is honored, and ayarn.lockwritten by Yarn Classic no longer gets installed by Yarn Berry. pnpm provides that package manager when the dependency pinned a version, or when the host cannot satisfy what the dependency needs — so a repository built with Yarn now installs on a machine that has only pnpm, while a host that already has a suitable one keeps using its own.pnpm dlx(pnx) runs one of them for a single command:pnx yarn@4 install,pnx npm@11 ci,pnx bun@1.3.0 install. Naming a package manager, or a runtime (node,deno,bun), there now provisions the real thing instead of installing the npm package that shares its name — unless the specifier locates a package rather than asking for a released version (pnx yarn@npm:yarn@1.22.22,pnx yarn@yarnpkg/berry), which installs what it names —pnx yarn@4was previously a missing version, since Yarn 4 is published as@yarnpkg/cli-dist, andpnx node@22now runs that Node.js release rather than a wrapper that downloads one.--packagenaming a package manager picks which of its commands to run, sopnx --package npm@11 npx create-somethingruns that npm'snpx.pnpm shim add yarnlinks ayarncommand that runs whatever version the current project pins, andpnpm shim rm/pnpm shim lsmanage those shims. It works for any package, not only package managers. Shims are never created as a side effect ofpnpm setupor an install — a shim shadows the rest of yourPATH, so pnpm only writes one when asked.Installing a package manager globally (
pnpm add -g yarn) now makes it follow a project's pin too, the way a globally installed Node.js already followsdevEngines.runtime: the pinned version runs where a project pins one, and the globally installed copy is the fallback everywhere else. An explicitglobalShimsentry, includingfalse, is left as you set it.pnpm addfollows the same rule about what a name means.pnpm add -g yarn@4installs Yarn Berry — it used to fail, because npm'syarnpackage stops at Classic — andpnpm add -g node@22/pnpm add -g deno@2install that Node.js or Deno release rather than a wrapper package that downloads one. In a project, naming a package manager records which one the project uses instead of installing it as a dependency, and naming a runtime records it underengines.runtimeasnode@runtime:22already did.The declaration goes where the package manager reads it. Yarn is started from a project pin by corepack, which reads only
packageManagerand only accepts an exact version there, sopnpm add yarn@4resolves the line and writes"packageManager": "yarn@4.18.0"— the same thingcorepack use yarn@4writes, down to the+sha512.…integrity for the Yarn Classic line that corepack pins its tarball with. Every other package manager is recorded indevEngines.packageManager, which holds a range. Only one of the two fields is ever left behind: they declare the same thing, and corepack refuses to run a project whose declarations disagree.A JavaScript package manager on a machine without Node.js gets a managed LTS runtime to run on.
What changes for a project coming from v11:
pnpm add yarnrecords the project's package manager instead of installing the npm package that shares the name (that package is still reachable aspnpm add yarn@npm:yarn@1.22.22),pnpm add -g yarninstalls the current Yarn line rather than Classic,pnpm add -g node/pnpm add -g denoandpnx node/pnx denoinstall a Node.js or Deno release rather than a wrapper package, and a globally installed package manager defers to a project's pin where there is one.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
remoteSideEffectsCachesetting. A workspace names the eligibleorganizationandpackages; everything describing the act of signing —publish,keyId,builderId,trustedKeys,privateKeyand the provenance fields — is refused inpnpm-workspace.yamland read from the global config file or the environment instead.Added the
audit.ignorePrunesetting. When set totrue,pnpm audit --fixremoves ignored GHSA entries that no longer appear in the audit report.pnpm initnow pins the latest pnpm version, instead of the version of pnpm that ran the command. A project scaffolded by an outdated pnpm therefore no longer inherits that staleness through its owndevEngines.packageManager/packageManagerpin #7490.The version is read from the
latesttag on the package-manager registries. When that lookup cannot answer — no network, an unreachable or slow registry,offline, or alatestthat theminimumReleaseAge/trustPolicysettings reject —pnpm initpins the running version as before, and never fails or hangs on the lookup. Alatestthat is older than the running pnpm is never pinned either.Allowed
pnpm update --patchesto refresh registry revisions through a configured pnpr server while retaining locked package versions.Added explicit registry revision selection with
<version>+rNandpnpm update --patchesfor refreshing revision artifacts without changing package versions. Registry-backed lockfile policy checks recognize historical revisions, and pnpr now preserves safe revision histories from upstream registries.Added support for registry replacement tarballs using standard integrity values, explicit revision fields, registry routing from the
registriessetting, non-redirecting integrity-addressed URLs, canonical safe-integer revision numbers, and pnpr proxying for immutable upstream revision artifacts.Running
pnpm setup,pnpm self-update, or a command that modifies the global installation (such aspnpm add --global) throughsudonow fails withERR_PNPM_SUDO_NOT_SUPPORTEDinstead of silently operating on the root user's home directory. pnpm keeps global packages and configuration in the invoking user's home directory, so these commands never need root permissions. Read-only global commands (such aspnpm bin --global) still work under sudo.pnpm stage approvenow approves several staged packages at once. Run it without a stage id to pick from the staged versions interactively, or pass a list of stage ids. The whole batch is approved with a single one-time password, and pnpm asks for a new one only once the registry stops accepting it. Inside a workspace, the selected packages are approved in dependency order, and a package whose workspace dependency could not be approved is skipped instead of being published against a dependency that never reached the registry.Patch Changes
Deprecated the pnpmfile
filterLoghook in pnpm v12. The Rust CLI ignores it and emits a warning.The built-in compatibility database no longer adds dependencies that were detected by static analysis of published packages. Those entries named packages that are only imported for their types, so installing them was at best unnecessary and at worst broke the dependent:
@typescript-eslint/typesgained atypescriptdependency resolved to the newest release, which put TypeScript 7 under older@typescript-eslintversions and made ESLint fail with "Cannot read properties of undefined (reading 'Intrinsic')". The database keeps its@yarnpkg/extensionsentries and pnpm's own curated ones.When no directory above the project accepts a hard link — inside an AI agent sandbox that only grants write access to the project, or a container with just the project mounted writable — the default store is now created at
<project>/node_modules/.pnpm-storeinstead of in the pnpm home directory. In those environments the home store is either read-only or on another volume, which forces every package to be copied instead of hard linked #13525.Platinum Sponsors
Gold Sponsors
v12.0.0-rc.11: pnpm 12 RC 11Compare Source
Minor Changes
pnpm stage approvenow approves several staged packages at once. Run it without a stage id to pick from the staged versions interactively, or pass a list of stage ids. The whole batch is approved with a single one-time password, and pnpm asks for a new one only once the registry stops accepting it. Inside a workspace, the selected packages are approved in dependency order, and a package whose workspace dependency could not be approved is skipped instead of being published against a dependency that never reached the registry.Patch Changes
Under
nodeLinker: isolated, a Bit root-component member whose materialized copy carries nopackage.jsonnow receives sibling symlinks for the dependencies its own lockfile snapshot declares, instead of a symlink to every other member of the root. The all-member fallback remains only when no snapshot exists.The update notification now suggests
pnpm self-updatewhenPNPM_HOMEmanages the pnpm in use, and the standalone install script otherwise — under Corepack, or when another package manager installed pnpm.pnpm self-updateunder Corepack names the standalone install script too.Platinum Sponsors
Gold Sponsors
v12.0.0-rc.10: pnpm 12 RC 10Compare Source
Patch Changes
Fixed pnpm v11 incorrectly reporting
confirmModulesPurgeas unrecognized when set inpnpm-workspace.yaml. The Rust CLI now identifies the unsupported option as a pnpm v11 setting instead of suggesting an unrelated setting.A
+<algorithm>.<hash>build in adevEngines.packageManagerversion no longer makespnpm install --frozen-lockfilefail withERR_PNPM_FROZEN_LOCKFILE_WITH_OUTDATED_LOCKFILEon a lockfile a plain install kept rewriting identically #14124.The built-in compatibility database no longer adds dependencies that were detected by static analysis of published packages. Those entries named packages that are only imported for their types, so installing them was at best unnecessary and at worst broke the dependent:
@typescript-eslint/typesgained atypescriptdependency resolved to the newest release, which put TypeScript 7 under older@typescript-eslintversions and made ESLint fail with "Cannot read properties of undefined (reading 'Intrinsic')". The database keeps its@yarnpkg/extensionsentries and pnpm's own curated ones.pnpm install --frozen-lockfileno longer fails withERR_PNPM_FROZEN_LOCKFILE_WITH_OUTDATED_LOCKFILEwhen the pinned pnpm version recorded inpnpm-lock.yamlhas to be re-resolved before it can be installed. It runs the pnpm version the lockfile pins and leaves the lockfile unchanged #14124.Under
nodeLinker: hoisted, peer-resolution variants of an injected directory dependency (afile:snapshot) are materialized as separate copies again instead of collapsing onto the first-seen variant. Each copy keeps its own peer-resolved dependency set, so a project pinning one peer version no longer resolves another project's variant — Bit root components with conflicting peers across injected copies rely on this.Fixed
pnpm install --merge-git-branch-lockfiles --frozen-lockfilefailing withERR_PNPM_OUTDATED_LOCKFILEwhen a branch lockfile predates the removal of a dependency, or its move to another dependency group #13966. A dependency that no project declares anymore is no longer reinstated by the merge, and the packages it was the only path to are dropped with it.Record the pnpm version a project pins even when the install has nothing else to do. Adding a
devEngines.packageManager(orpackageManager) pin to a project whose dependencies are already installed leftpackageManagerDependenciesunwritten, sopnpm install --frozen-lockfilefailed withERR_PNPM_FROZEN_LOCKFILE_WITH_OUTDATED_LOCKFILEwhile a plainpnpm installreported "Already up to date" without recording it #14124.pnpm install --frozen-lockfileno longer fails whenpnpm-lock.yamlrecords the pinned pnpm version alongside an engine package the running pnpm does not install it from. An entry pinning another version is still refused, and a plain install rewrites the block #14124.Platinum Sponsors
Gold Sponsors
v12.0.0-rc.9: pnpm 12 RC 9Compare Source
Major Changes
A project's
pnpm-workspace.yamlmay no longer carry a setting pnpm does not recognize. Such a setting used to be ignored in silence — a misspelledminimumReleaseAgedropped the policy it was meant to set, and nothing said so. Now it is reported, suggesting the closest real setting name when the key looks like a typo, and it fails the command withERR_PNPM_UNRECOGNIZED_WORKSPACE_SETTINGSwhen the project pins a pnpm version the running pnpm satisfies: with the pin honored, the setting cannot be meant for a different pnpm version, so it is a mistake to fix rather than a key to ignore. Everywhere else it is a warning, so a project that has yet to be cleaned up keeps working.The
pnpm configsubcommands never fail on such a setting, so a broken file can still be inspected and repaired, andpnpm config get <key>prints the value with no warnings at all. Keys the global config file cannot set are likewise split between workspace-only settings (still directed topnpm-workspace.yaml) and settings unknown to this version.Minor Changes
Added global build approvals pnpm/pnpm#14101.
Added recursive global outdated checks pnpm/pnpm#14101.
pnpm config getandpnpm config listnow show the settings pnpm acts on under their documented names:registriesshows the registries pnpm resolves from, merged across every source (.npmrc,pnpm-workspace.yaml, the global config, CLI flags), in the shape the setting is written in: keyed by registry URL, with the default registry declared as the bare@scope. Built-in routes are included — the@jsrscope and thenpmjsandghprefixes — unless pointed elsewhere. Previouslypnpm config get registriesprintedundefined.updateandauditshow the effective sections, whichever spelling set them. The deprecated internal spellings (updateConfig,auditConfig,auditLevel) are no longer listed.catalogsshows the complete resolved catalog set — the singularcatalogblock is itsdefaultentry — whichever spelling declared it.registryand@scope:registryentries show the merged routes rather than raw.npmrcvalues, so they always agree with theregistriesview.Added support for configuring
stateDirin the Rust pnpm CLI pnpm/pnpm#12042.Added bounded workspace concurrency for recursive run and exec commands pnpm/pnpm#14101.
@pnpm/napigained reporter output, reverse dependency queries, and lockfile access.installandrebuildacceptoptions.reporterand render pnpm's terminal output — progress line, packages-diff summary, lifecycle output, and theDone in …footer. Rendered output goes to stdout, or to anonOutputcallback for a host that writes its own output through JavaScript. New reporting options:hideLifecycleOutput,ignoredBuildsInstructionText, andhideLinkedPkgsDiff.getDependentsreturns the reverse dependency trees behindpnpm why, annotated with thepackage.jsonfields named inmanifestFields.renderDependentsreturns those trees rendered as tree, parseable, or JSON output.readLockfileandwriteLockfileread and writepnpm-lock.yaml(or the current lockfile under the virtual store).filterLockfileByImportersreturns a lockfile narrowed to what the named importers reach.readModulesManifestreturns the.modules.yamlstate of an installednode_modules.Top-level lockfile keys pnpm does not define are no longer dropped when a lockfile is loaded and saved, so state a tool records beside pnpm's own keys survives a rewrite.
pnpmnow supports per-branch lockfiles in its Rust engine:gitBranchLockfilegives each git branch its ownpnpm-lock.<branch>.yaml, so two branches can hold different resolutions without conflicting on one file. A branch that has no lockfile yet installs against the sharedpnpm-lock.yaml.mergeGitBranchLockfiles(and the--merge-git-branch-lockfilesflag onpnpm install) folds every branch lockfile back intopnpm-lock.yamland deletes them, which is what merging a branch into the mainline needs.mergeGitBranchLockfilesBranchPattern(and--merge-git-branch-lockfiles-branch-pattern) names the branches that merge automatically, so a mainline branch does not have to pass the flag by hand #12042.Added
PNPM_CONFIG_VIRTUAL_STORE_ONLYandPNPM_CONFIG_ENABLE_MODULES_DIRsupport to the Rust pnpm CLI.Added support for the
lockfileDirsetting and its--lockfile-dir <dir>flag onpnpm install,add,update, andremove.pnpm-lock.yaml, the rootnode_modulesholding the virtual store, and the config dependencies now live in the given directory, each project is recorded under its path relative to it, and every project keeps its ownnode_modulesof symlinks — so several projects can share one lockfile #12042.Added support for the
preferSymlinkedExecutablessetting. On POSIX systems,node_modules/.binentries are created as symlinks to the executable files instead of shell shims, andNODE_PATHpointing at the virtual store of the workspace root is exported to spawned scripts so they can resolve dependencies from the hoisted store. Like the TypeScript CLI, the setting turns on automatically whennodeLinkeris set tohoisted.Added the six CLI flags the TypeScript pnpm CLI accepts but the Rust CLI did not #14101:
--streamprints a recursive command's script output as it arrives, one line at a time, prefixed with the project it came from, instead of letting the scripts write to the terminal directly.--parallelimplies it, as in pnpm.--aggregate-outputholds each script's streamed output until the script exits and then prints it as one block, so concurrent projects can't interleave.--reporter-hide-prefixdrops that project prefix from the scripts' own output lines. On a recursivepnpm exec, the opposite spelling--no-reporter-hide-prefixturns the prefixing on.--use-stderrsends the reporter's output to stderr, leaving stdout for the command's own result.--ignore-workspaceruns the command as if the project were standalone: no workspace root is discovered, sopnpm-workspace.yamlcontributes neither settings nor sibling projects, and a blocked dependency build is not scaffolded into itsallowBuilds.--workspace-packagesoverrides thepackagespatterns ofpnpm-workspace.yamlfor the run.The
stream,aggregateOutput,reporterHidePrefix,useStderr, andignoreWorkspacesettings are now read frompnpm-workspace.yaml, the globalconfig.yaml, and theirPNPM_CONFIG_*environment variables too.Added support for the
shellEmulatorsetting. With it enabled, the scriptspnpm runexecutes, a project's own lifecycle scripts, and dependencies' build scripts run in a built-in POSIX shell instead of the platform's (sh -c, orcmd /d /s /con Windows), so scripts written forshbehave the same on every OS.scriptShellis not used while the emulator is on.The Rust engine now checks that a package read back from the store is the package it was recorded as. When the tarball's
package.jsonnames a different name or version than the store entry was keyed for — a broken lockfile, or a registry serving content that doesn't match its metadata — the install fails withERR_PNPM_UNEXPECTED_PKG_CONTENT_IN_STORE. Set the newstrictStorePkgContentChecksetting tofalseto downgrade the failure to a warning and install from the entry anyway #12042.pnpmnow supports three workspace settings in its Rust engine:includeWorkspaceRoot(and the universal--include-workspace-root/--no-include-workspace-rootflags) keeps the workspace root project in a recursiverun,exec,add, ortest, which otherwise leave it out.ignoreWorkspaceCyclesanddisallowWorkspaceCyclescontrol the report an install makes when workspace projects depend on each other in a cycle: it is a warning by default, anERR_PNPM_DISALLOW_WORKSPACE_CYCLESerror underdisallowWorkspaceCycles, and silent underignoreWorkspaceCycles#12042.Added support for the remaining pnpm default settings, including recursive command controls, optional dependency selection, workspace-root checks, color modes, lockfile compatibility, and pack manifest options.
Batch workspace publishing accepts a shared scope-specific credential, rejects mismatched credentials for a registry before publishing, and runs the
publishandpostpublishscripts after each completed registry group pnpm/pnpm#14101.Added the commands the Rust CLI was still missing:
pnpm get <key>andpnpm set <key> <value>— the top-level spellings ofpnpm config getandpnpm config set.pnpm store status— reports the packages whose files no longer match the store they were expanded from, failing withERR_PNPM_MODIFIED_DEPENDENCY; andpnpm store add <pkg>...— fetches packages into the store without writing a manifest, a lockfile, ornode_modules.pnpm env use --global <version>andpnpm env list [<selector>], the deprecated Node.js-only front end topnpm runtime.pnpm edit,pnpm profile,pnpm token, andpnpm xmasnow fail withERR_PNPM_NOT_IMPLEMENTEDpointing at the npm CLI, instead of being taken for a package script.An install that resolves the dependency graph now reports the unmet peer dependencies it leaves behind, matching the TypeScript CLI. By default it warns once —
Issues with peer dependencies found. Run "pnpm peers check" to list them.— and withstrictPeerDependenciesit fails withERR_PNPM_PEER_DEP_ISSUESafter the artifacts are written, listing every unmet peer. This coverspnpm install,add,remove,updateand--lockfile-only;pnpm dedupereported the same verdict already, and now shares the reporting with them.peerDependencyRulesare applied before the verdict, so a rule that covers every issue leaves nothing to report, and a--filtered install reports only on the projects it installed. An install that skips resolution — a frozen install, or one whosepnpm-lock.yamlis already up to date — reports nothing, as in the TypeScript CLI;pnpm peers checkinspects such a tree #14098.Added
fetchWarnTimeoutMsandfetchMinSpeedKiBpsto the Rust pnpm CLI and its N-API bindings. Slow registry metadata requests and tarball downloads now emit pnpm-compatible warnings without exposing URL credentials, query parameters, fragments, or control characters pnpm/pnpm#12042.Added filtered and split SBOM generation with per-project lockfiles, including reachable workspace projects and incomplete-graph validation pnpm/pnpm#14101.
Patch Changes
Kept pending build approvals available after removing an unrelated dependency.
Fixed resolving the
chcpcommand on Windows duringpnpm setupby looking forchcp.combeforechcppnpm/pnpm#13991.A custom fetcher can no longer replace the archive integrity that
pnpm-lock.yamlpins: the locked value is restored after acanFetchorfetchhook rewrites the resolution, and delegating a locked archive to a directory or git source now fails instead of installing unverified content.The Rust CLI now also loads the pnpmfiles named by the
pnpmfilesetting (a single path or an ordered list), and hands custom fetchers nativelocalTarballandremoteTarballcallbacks — including on a fresh install that has to compute a missing tarball integrity, which is then reused by later offline installs. File maps a fetcher returns are accepted only when they match what those native callbacks extracted.pnpm dedupeaccepts thepnpm installoptions that pnpm documents for it —--lockfile-only,--ignore-scripts,--offline, and--prefer-offline— instead of rejecting them withunexpected argument. Without--lockfile-only,pnpm dedupenow also updatesnode_modules, as an install does #14107.pnpm dedupein the Rust engine now fails withERR_PNPM_PEER_DEP_ISSUESwhenstrictPeerDependenciesis set and unresolved peer dependency issues remain after deduplication, matching the TypeScript CLI #14099. Previously it only ever printed a warning, regardless of the setting.pnpm deploy --prodandpnpm deploy --no-optionalno longer list the excluded dependency groups in the deployedpackage.jsonandpnpm-lock.yaml. The deployed lockfile referenced packages that the deploy left out of its graph, so installing in the deploy directory afterwards created dangling symlinks #13623.pnpm install --devandpnpm deploy --devno longer install optional dependencies, and--prodnow takes precedence when combined with--dev, matching the TypeScript pnpm CLI.A dependency published with
"bin": "", such asurl-loader@1.1.2, no longer fails the install withERR_PNPM_CMD_SHIM_PROBE_SHIM_SOURCE#13962. An emptybindeclares no command, as it does in pnpm v11, so no shim is written for the package; adirectories.binentry on the same package is still linked.A dependency pinned to an exact version carrying semver build metadata (
"@parcel/codeframe": "2.0.0-canary.1718+d8408010f") installs again instead of failing withERR_PNPM_NO_MATCHING_VERSION#14096. npm strips build metadata when it publishes a version, so pnpm strips it from the version it looks up, matching npm and pnpm v11.A package's
filesentries now match only at the package root, the way npm reads them. A baresrcused to also match nested directories such asexample/src, so a dependency installed from git could ship the repository's own example app. The same filter decides whatpnpm packandpnpm publishput in a tarball and whatpnpm deploycopies, so those stop carrying the extra files too. Exclusions such as!**/__tests__and!*.mapstill match at any depth. A package already in the store keeps its old file set until it is fetched again.A
pnpm install --filter <selector>run that has nothing to do now reports "Already up to date" without entering the install pipeline, the same way an unfilteredpnpm installalready did #14033.On Windows, upgrading pnpm no longer leaves a stale
pnpm.ps1behind. PowerShell resolvespnpm.ps1ahead ofpnpm.cmd, so a shim written by an older installation kept running the previous version. Linking the pnpm CLI's bins now deletes it #13919.Settings written to a
pnpm-workspace.yamlblock that uses inline (flow) YAML —catalog: { foo: ^1.0.0 },overrides: { foo: 1.0.0 },minimumReleaseAgeExclude: [foo@1.0.0]— are now edited in place instead of failing or corrupting the file.pnpm audit,pnpm link,pnpm approve-builds,pnpm patch,pnpm add --config, and catalog updates all keep the block's flow style, its other entries, and its comments #14108.A frozen install no longer rewrites the
packageManagerDependenciesblock ofpnpm-lock.yaml. When the pnpm version pinned bydevEngines.packageManager(or bypackageManager) is missing from the lockfile or no longer matches it,--frozen-lockfilenow fails withERR_PNPM_FROZEN_LOCKFILE_WITH_OUTDATED_LOCKFILEinstead of resolving the version and saving it, so a manifest whose pin was bumped without regenerating the lockfile can no longer pass CI #14009.When a git-hosted dependency is blocked from running build scripts, the error now suggests an
allowBuildsentry that actually approves it. It quoted the bare package name, which never matches a git-hosted package, so following the suggestion left the install failing the same way #14002.A git dependency installed over HTTPS from a hosted repository now keeps its branch, tag, or version range in the specifier recorded in
package.json. It was written back without one, so the nextpnpm updatemoved the dependency to the repository's default branch #13999.Added support for the
globalPnpmfilesetting, which names a user-level pnpmfile that runs for every project ahead of the project's own. Like pnpm, it is left out of the lockfile'spnpmfileChecksum, so editing it does not decide whether a lockfile is still current.pnpmfileandglobalPnpmfileare now also readable fromPNPM_CONFIG_PNPMFILEandPNPM_CONFIG_GLOBAL_PNPMFILE.Fix recursive
pnpm update <name>@<version>so an exact pinned update stays scoped to the requested version line: copies of the same package on another major line — or, for a0.xrequest, another minor line — keep their locked resolution instead of being re-resolved along with the target.Under
nodeLinker: hoisted, a dependency declared against a peer-resolution variant of a package version is no longer dropped from the installed layout. All variants of a version share one hoisted copy, and edges pointing at any of them now resolve to it, so the depending project keeps the package in its.package-map.jsonand the depending package keeps it in itsnode_modules/.bin.A repeat
pnpm installwithnodeLinker: hoistedis a no-op again when a workspace package declarConfiguration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.