Update pnpm to v12 - #146
Open
elastic-renovate-prod[bot] wants to merge 1 commit into
Open
elastic-renovate-prod[bot] wants to merge 1 commit into
elastic-renovate-prod[bot] wants to merge 1 commit into
Conversation
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
July 17, 2026 00:14
41820df to
1b771cd
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
July 23, 2026 04:15
1b771cd to
92a9602
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
July 25, 2026 00:14
92a9602 to
d2c434a
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
July 25, 2026 16:15
d2c434a to
e11eb61
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
July 27, 2026 00:15
e11eb61 to
7bf30b5
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
July 30, 2026 00:14
7bf30b5 to
194b289
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
July 30, 2026 20:18
194b289 to
8270d51
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
August 5, 2026 08:15
8270d51 to
7c5b7fa
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
August 7, 2026 12:14
7c5b7fa to
73edc75
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
August 10, 2026 16:15
73edc75 to
ade7ffd
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
August 16, 2026 16:15
ade7ffd to
1c67a51
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
August 22, 2026 20:15
1c67a51 to
bb02869
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
August 30, 2026 16:15
bb02869 to
3fa3cdf
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
August 31, 2026 16:14
3fa3cdf to
9538cfe
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
September 5, 2026 16:14
9538cfe to
9af94f9
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
September 5, 2026 20:15
9af94f9 to
f2bef8a
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
7 times, most recently
from
September 15, 2026 12:15
13550c3 to
063c7c5
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
2 times, most recently
from
September 23, 2026 04:17
a1b3f07 to
c912199
Compare
elastic-renovate-prod
Bot
force-pushed
the
renovate/pnpm
branch
from
September 27, 2026 12:16
c912199 to
ec0a760
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:
11.9.0→12.5.112.6.0Release Notes
pnpm/pnpm (pnpm)
v12.5.1: pnpm 12.5.1Compare Source
Patch Changes
pnpm now reports an unknown task setting in
pnpm-workspace.yamland carries on. It used to refuse to start, so a project could not use a task setting that only the pnpm version itspackageManagerpins reads. The setting is still an error when the running pnpm is that pinned version.Python interpreter installation now retries historical release metadata requests. It caches the release list for up to 24 hours and refreshes it once after a lookup miss. When a release omits the current platform, the search samples at most eight other releases before reporting that the lookup is inconclusive.
Python
registriesentries now route packages by exact names or trailing-prefix patterns inpackages. Registry declaration order no longer affects resolution. A matched package resolves exclusively from its assigned registry, including transitive and build dependencies. Usepackages: ["*"]to declare the default index.pnpm installno longer fails with "Too many levels of symbolic links" when a Cargo configuration file above the workspace is a symlink, such as a~/.cargo/config.tomllinked from a dotfiles repository.pnpm installnow returns "Already up to date" in a workspace wherededupeDirectDepsleft a project without anode_modulesdirectory of its own. Such a project forced a full install on every run.pnpm installno longer refuses the repeat-install fast path just because a changedpnpm-lock.yamlis 16 MiB or larger. Such a lockfile forced a full install on the run after every change.Platinum Sponsors
Gold Sponsors
v12.5.0: pnpm 12.5Compare Source
pnpm 12.5.0 makes Python a first-class ecosystem, accepts Package URLs in
pnpm add, names whole platforms insupportedArchitectures, and gives tasks machine-wide concurrency limits. It also fixes an install that could reuse one package's downloaded tarball for another.Minor Changes
Installing packages
pnpm addaccepts a Package URL in place of a package name.pnpm add pkg:npm/express@4.18.2savesexpresstopackage.json.pnpm add pkg:cargo/serde@1.0.188savesserdetoCargo.toml.pnpm add pkg:pypi/requests@2.31.0savesrequeststopyproject.toml.pkgis now a reserved specifier prefix, whatever case it is written in, so a named registry can no longer be calledpkg.A
registriesentry can now name the ecosystem it serves.ecosystemacceptsnpm,cargoandpypi. An entry that does not name one serves npm, as every entry did before.An ecosystem with several indexes searches them in the order they are declared. The first index that has a package supplies it, so the one declared last answers what none before it had.
A
registriesentry may not carry credentials. pnpm reads them from.npmrc, matched by origin, for a PyPI index as for every other package source.Configuring pnpm
supportedArchitecturesnow accepts a list of platforms, in place of theos,cpuandlibcaxes.An install prepares for the platforms the list names, and for those only. A platform reads as
<os>-<cpu>, with a C library on Linux, as inlinux-x64-muslorlinux-x64-manylinux_2_28. The Rust target triple of the same machine is accepted too, sox86_64-unknown-linux-gnunames the platformlinux-x64names. A Linux platform that names no C library is the glibc platform.currentis the platform the install runs on.The
os,cpuandlibcmapping keeps working and keeps its meaning.Added concurrency groups for tasks. A task in
pnpm-workspace.yamlcan name aconcurrencyGroup. The newconcurrencyGroupssetting gives each group a limit. At most that many tasks of the group run at once on the machine, counted across every pnpm process,pnpm pipelineincluded. A task past the limit waits for a running one to finish. A script that callspnpm runfor a task of the same group runs under the slot its parent holds.toolsnames the programs pnpm downloads, andmirrorsays where each one comes from.node,bunandpythoncan be named. Any other tool is refused.mirroris the base a tool's own layout hangs off.channelssends one release channel elsewhere. A channel neither it nornode-mirror:<channel>names is left tomirror. Onlynodepublishes channels, so naming them for another tool is refused.Set it in the global
config.yamlor inPNPM_CONFIG_TOOLS. Apnpm-workspace.yamlthat names a tool mirror is ignored.pnpm pack-appdownloads the Node.js it embeds throughtools.node.node-mirror:<channel>keeps working and names the same thing as an entry underchannels.Python interpreters and environments
pnpm installnow chooses a Python interpreter for each project instead of installing every project with one interpreter #14945. A project is installed with the first interpreter on the machine that itsrequires-pythonaccepts, so a workspace can hold projects that support different Python versions. pnpm reads.python-versiontoo, and prefers the version it asks for. Setpython.executableinpnpm-workspace.yamlto name one interpreter for every project.pnpm installnow installs a Python interpreter when no interpreter on the machine fits the project #14945. The builds are python-build-standalone's, which uv and rye install too. One interpreter is shared by every project on the machine, and a later install uses it without downloading anything.runtimeOnFaildecides what an install with no interpreter that fits does, the way it does for a Node.js runtime.errorreports the project instead of installing one.warnandignoreinstall with an interpreter the machine has that the project'srequires-pythonrejects.tools.python.mirrornames a mirror.Python environments now live in the store. Each project keeps only its
.venvlink, which points at the project's current environment generation underpython-envsin the store. A repository with many Python projects no longer holds a.pnpm/python-envsdirectory in each of them. The next install relinks a.venvthat an earlier release published. The old.pnpm/python-envsdirectory is left in place, since a running program may still use it, and can be deleted once none does. WithfrozenStoreset, pnpm writes nothing to the store, so environments stay in the project's.pnpm/python-envs#15014.Python environments now use
packageImportMethodto import wheel files from the store. Useclone-or-copyfor copy-on-write clones with a copy fallback, orcopyfor independent files. Hardlinked files share writes with the store and other environments.Isolated Python build environments keep backend writes private with copy-on-write clones or copies.
Python projects and workspaces
pnpm installnow installs a Python project's own package, so the project can be imported and the commands in[project.scripts]run right after an install #14945. The installed package points at the source tree, so an edit to a module takes effect without another install. pnpm installs the package of a project that declares a[build-system].tool.uv.packageoverrides that either way.pnpm installnow installs a Python project in the workspace from its own source. Declare it under[tool.uv.sources], asshared = { workspace = true }orshared = { path = "../shared", editable = true }. pnpm builds the project with the backend it declares. It installs the build editable, so an edit to the project takes effect without another install.Approve the build backend under
allowBuildsinpnpm-workspace.yamlas a Package URL, aspkg:pypi/hatchling: true. An install that has not approved a backend does not build the projects that need it. The message names the key to add.pnpm installnow refuses a requirement that names a project in the workspace when nothing declares where it comes from. It used to take that name from the index.The members of a uv workspace can now share one Python environment. Set
shared-environment = trueunder[tool.pnpm.python]in thepyproject.tomlthat declares[tool.uv.workspace].pnpm installthen resolves every member as one graph into onepylock.tomland one.venvat the workspace root. Two members that require versions of a distribution no release satisfies at once are refused with an error naming both. Each project still gets an environment of its own by default #15015.Python projects can now select extras and dependency groups through
[tool.pnpm.python]inpyproject.toml#14945. Workspacepython.extrasandpython.groupsdefaults now skip names a project does not define.pnpm installnow reads dynamic Python project metadata from the build backend #14945. Projects with only arequirements.txtfile now get a Python environment and lockfile.Python dependencies and lockfiles
pnpm can now resolve
pylock.tomlfor several platforms and Python versions at once.supportedArchitecturesnames the platforms to lock for andpython.versionsthe versions. Every platform is paired with every version. One committed lockfile then serves Linux CI and macOS or Windows contributors #14945.The lockfile pins the wheel each environment takes for a distribution. It marks a package only some environments install.
pnpm installtakes the packages and wheels of the environment its interpreter matches, and refuses an interpreter none of them stand for. pnpm resolves a project that declares environments itself, not through the serverpnprServernames. Naming neither setting locks for the interpreter running the install.python.overridesandpython.constraintspin the versions a Python resolution may pick #14945. pnpm reads uv's own overrides and constraints frompyproject.tomltoo.pnpm installnow supports Python dependencies from Git repositories #14945. Direct wheel URLs are also supported. Sources can be declared in[tool.uv.sources]. Git dependencies requireallowBuildsapproval.pnpm installcan install a Python release that publishes no wheel this interpreter accepts, by building the source distribution the index serves beside it #14945. The archive is pinned inpylock.tomlby name and SHA-256. A later install replays it from the store, offline included. Building a source distribution runs the release's own build backend. Approve it withpkg:pypi/<distribution>: trueunderallowBuilds.A resolution that finds no version of a distribution now says why. It tells apart a distribution no index publishes, one whose releases publish nothing this interpreter can install, and one whose versions the project's requirements exclude.
Patch Changes
Installing packages
pnpm no longer reuses one package's downloaded tarball for another package whose resolution pins a different integrity hash to the same URL #15021.
pnpm installandpnpm addnow report an error whenpackage.json,pnpm-lock.yaml,pyproject.tomlor another file they snapshot before installing is a named pipe or a device. The command used to wait forever for something to write to it.pnpm install --prodandpnpm install --devnow record every dependency group inpnpm-lock.yaml.node_modulesstill holds only the groups the filter selects. They used to write the filter into the lockfile, so a laterpnpm install --frozen-lockfilerejected it.pnpm prune --prod,pnpm prune --dev, andpnpm prune --no-optionalbehave the same way #14912.POSIX bin shims now convert a Windows-form path such as
C:\node_modules\.bin\tsccorrectly. The shim mangled the backslashes in such a path and could not reach the package it runs. Installing again replaces the shims already innode_modules#14867.Two pnpm processes installing one workspace at the same time no longer fail on Windows with "Access is denied" while writing
node_modules/.pnpm-workspace-state-v1.json. The write now retries the transient lock the other process holds, as pnpm's other file writes do.pnpm now reads the manifest from the tarball when a pnpmfile
resolvershook returns a resolution without one. Such a package installed alone, with none of its own dependencies and no warning #15000.pnpm installnow merges Git conflict markers inpnpm-lock.yaml. It parses both sides of the conflict and keeps the versions they locked. A conflict in the config dependencies recorded at the top of the lockfile is merged too #14880.Cargo projects
pnpm installcan now generateCargo.lockfor workspaces with path or Git[patch]and[replace]overrides. Adding, removing, and updating crates also preserve these overrides #14950.Cargo lockfile resolution blocks unsupported Git transport helpers declared by transitive dependencies.
pnpm installnow vendors recursive Git submodules for Cargo dependencies at their pinned commits. Cargo builds can use these sources offline. Set Git'sprotocol.file.allowtoalwaysto fetch local file submodules. pnpm fetches cached Git crates again on the first online install #14951.pnpm installnow generatesCargo.lockfor workspaces with Git dependencies, including a dependency that omits a package version. It also downloads the Rust standard library's dependencies when Cargo configuration enablesbuild-std#14944.pnpm installnow handles weak Cargo features, writtencrate?/feature. Resolution failed when one dependency turned on an optional crate and another asked for a weak feature of it #14960. The generatedCargo.locknow also includes the dependencies weak features reference, which Cargo rejected with--lockedfor crates such asuuid#14978.pnpm installnow generatesCargo.lockwhen a crate version it considers depends on a release the registry carries only as yanked. pnpm rules that version out and resolves the rest of the graph. Resolution failed with an error such asno non-yanked version of napi-build satisfies ^3.0.0-beta#14952.pnpm installnow falls back to an older semver-incompatible version of a crate when the newest one a dependency range allows cannot be resolved. Ranges such as>=1, <3span several of them #14962.Python projects
pnpm installnow honors uv workspace members when discovering Python projects. When no uv workspace declares a project, pnpm skips projects under conventional example, demo, documentation, template,test,tests, and test fixture directories #15058.pnpm install --filter <selector>now installs only the Python projects the selection asks for. A Python project that shares a directory with an npm workspace project is selected with that project. A Python project in a directory of its own is selected by the distribution it declares, by its path, or through the[tool.uv.sources]entries that reach it. Under--fail-if-no-match, a selector that names only a Python project is a match.pnpm add --filter <selector> pypi:<package>writes the requirement to every selected project #14945.pnpm installnow installs wheels whoseRECORDhashes disagree with their contents. The wheel archive's locked SHA-256 hash remains verified. pnpm writes correct hashes to the installedRECORD#15061.pnpm installnow installs a Python wheel whoseWHEELfile lists tags that differ from the ones in its filename. A wheel whose filename tags were changed after the build, such asmysql-connector-python, was rejected #14945.A Python release whose wheel metadata declares a requirement pnpm cannot read no longer fails the install. pnpm now resolves the project against the other releases of that package, and reports the unreadable requirement when none of them works.
pnpm installno longer fails when a Python index lists a file pnpm cannot use, such as a release with no SHA-256 digest or an unreadable wheel filename. That file is left out and the project resolves against the remaining releases.pnpm add pypi:<package>in a directory that has nopyproject.tomlnow names the missing file and says where to run the command. It used to fail with a bareNo such file or directory (os error 2)#14945.Performance
pnpm auditno longer hangs on dependency graphs with many shared dependencies #15005.Sped up
pnpm installin Python workspaces with many projects. Projects now prepare concurrently. Projects with identical registry requirements also share fresh dependency resolutions #14945.Repeat installs through the Node-API bindings now return "Already up to date" when the project manifests still match
pnpm-lock.yaml. Before, every such install reinstalled the whole tree. An install also no longer reinstalls whenpnpm-lock.yamldiffers from the installed dependencies only by packages no project depends on or by top-level keys pnpm does not define.Other commands
pnpm deploynow links commands exposed by workspace dependencies into the deployed project'snode_modules/.bindirectory #14899.pnpm dlxandpnxnow prompt to approve dependency build scripts in interactive terminals #14943. Cached packages with pending builds also prompt for approval. Without an interactive terminal, use--allow-buildto allow the required builds.pnpm add -gandpnpm update -gnow ignore incomplete unrelated global package groups when every command from the replaced group is retained. Operations that could remove a global command still require complete ownership information.pnpm packnow writes tarball entries grouped by file extension and file name, the order npm uses. Packages that ship many same-named files, such as template collections, pack much smaller #14766.pnpm outdated --longfills the Details column with the package homepage again #14886.Platinum Sponsors
Gold Sponsors
v12.4.2: pnpm 12.4.2Compare Source
pnpm 12.4.2 includes security fixes for executable shims and GitHub Actions links, more reliable installs, faster peer dependency checks in workspaces, and Python lockfiles that work across compatible targets.
Patch Changes
Security
Dependency executables can no longer take over another package's POSIX bin shim through its shell helpers. Reinstall dependencies to replace existing shims #14837.
On Cygwin, MSYS2, and WSL, shims still use
PATHfor Windows path conversion, so dependency executables can still redirect them there.GitHub Actions homepage links no longer expose server credentials. GitHub server URLs now require HTTPS, with HTTP allowed only for loopback hosts.
Installing packages
pnpm no longer crashes at startup on FreeBSD and other Unix-like platforms. Platforms other than Windows and macOS use
~/.local/share/pnpm/storeby default #14859.pnpm installon Windows no longer fails withERR_PNPM_PACKAGE_MANAGER_REMOVE_MODULES_DIRwhen clearingnode_modulescontaining linked dependencies, such as when changingnodeLinker#14790.pnpm install <pkg>now accepts--prodand--dev, including--prod=false#14868.pnpm installandpnpm updatenow honor--ignore-workspacein nested projects excluded from the surrounding workspace. The flag also skips that workspace's settings during thepackageManagercheck #14809.pnpm installon macOS no longer reuses stale files forfile:tarball or git-hosted tarball dependencies.pnpm installin a single-project directory now detectspackage.jsonedits made while the previous install was finishing #14890.pnpm install --frozen-lockfilenow removes packages no longer reachable from any project inpnpm-lock.yaml. This also prevents repeated lifecycle script execution and unnecessary installs beforepnpm runandpnpm execwithverifyDepsBeforeRun#14891.Resolving and updating dependencies
Node.js runtime resolution now reports network failures from unofficial-builds.nodejs.org. These failures previously omitted musl builds from
pnpm-lock.yaml, making its contents depend on network access #14813.pnpm installnow rejects invalidpeerDependenciesspecifiers withERR_PNPM_INVALID_PEER_DEPENDENCY_SPECIFICATION. A value such as"foo": "foo@1.0.0"previously created a broken directory link #14791.pnpm deploynow writes plain registry versions in the deployedpackage.json, without peer dependency suffixes. The lockfile retains peer bindings, and npm aliases retain their target package names #14873.pnpm add <git repository>now names repositories without apackage.jsonas@owner/repo, allowing dependencies on equally named repositories from different owners #14870.Peer dependency resolution now deduplicates packages whose child dependency resolves an optional peer in only some workspace projects, such as
nextwithstyled-jsx's optionalbabel-plugin-macrospeer #14800.pnpm updatenow settles the lockfile in one run when an upgrade removes the package providing an optional peer dependency #14895.pnpm update --no-savenow preserves override-applied specifiers for dependencies it is not updating, preventing subsequent frozen installs from failing withERR_PNPM_OUTDATED_LOCKFILE#14836.pnpm update --no-savenow succeeds underminimumReleaseAgeStrictwhen every resolved version is old enough #14835.Performance
Workspace installs and
pnpm peers checkare faster when projects depend on each other, fixing a slowdown introduced in 12.3.0. Unmet peer dependencies of workspace packages are now reported only under projects that link them directly #14906.Hoisted installs use less memory when packages are cached. Frozen-lockfile hoisted installs on macOS are also faster when reusable package directories are cached.
Python projects
pnpm install --frozen-lockfilenow reusespylock.tomlacross compatible Python targets, including after kernel updates. Reuse requires unchanged requirements, index, andrequires-python, compatible wheels, and a locked dependency graph matching the target's markers #14843.The lockfile's
environmentsmarker now includes only the interpreter version and marker variables used by the dependency graph. Without--frozen-lockfile, pnpm warns and resolves again when the locked graph no longer matches the target.Python resolution no longer fails on malformed
Requires-Pythonvalues, such as the trailing comma inopenpyxl3.0.x. pnpm treats these releases as declaring no interpreter range #14910.pnpm add pypi:...now rejects unsupported--save-prefixvalues before editing the manifest or resolving dependencies.Workspaces and scripts
Scripts listed in
syncInjectedDepsAfterScriptsno longer fail withERR_PNPM_INJECTED_DEPS_SYNC_READ_DIRwhen the lockfile contains an injected package copy that no project depends on.shellEmulatornow expands${VAR},${VAR:-default}, and${VAR:+alternative}in scripts #14814.Cargo and Python project discovery now honors
!exclusions inpnpm-workspace.yamlpackages, skipping both parsing and generated source configuration for excluded projects #14844.pnpm --filter "./packages/{app,lib}"now selects either alternative. Brace alternatives can nest, span path separators, and combine with other wildcards.GitHub Actions updates now stop if an action reference changes during version resolution, and preserve unrelated workflow edits.
CLI and output
pn,pnpx, andpnxnow run the pnpm installed alongside them, even when that directory is absent fromPATHor another pnpm comes first #14803.pnpm --versionnow reports failures to install or record a project's pinned pnpm, then prints the running CLI's version. It also honors--store-dirand--store#14831.pnpm self-updateno longer reinstalls the active version when it was installed by the standalone installation script #14823.pnpm tandpnpm tstwork again as aliases forpnpm test.pnpm sbomnow emits valid repository URLs in CycloneDXexternalReferences[].urland SPDXhomepage. Shorthands such asvercel/msbecomegit+httpsURLs, embedded credentials are removed, and invalid repository values are omitted #14773.Platinum Sponsors
Gold Sponsors
v12.4.1: pnpm 12.4.1Compare Source
pnpm 12.4.1 fixes installs that failed on filesystems refusing hard links or clones, on Android, and under
nodeLinker: hoisted. Repeat installs are faster.Patch Changes
Installing packages
pnpm installno longer fails withOperation not permittedwhen the filesystem refuses a hard link or a copy-on-write clone #14722. UnderpackageImportMethod: autoandclone-or-copy, pnpm copies the file instead. EdenFS checkouts, which have no hard links, and rootless containers, which refuse the clone syscall, both hit this. An explicitpackageImportMethod: hardlinkorclonestill reports the error.pnpm also copies a package file whose store entry has reached the filesystem's limit on names for one file, 1024 on NTFS and 65000 on ext4. Such a file failed the install under
packageImportMethod: hardlink, and underautoit stopped pnpm hard linking for the rest of the install.pnpm installno longer writes a package file through a symlink left at the path it is importing to. Copying such a file overwrote whatever the link pointed at, and created that file when the link pointed nowhere. An executable package file also made the link's target executable.Fixed
pnpm installandpnpm dlxon Android. Registry requests crashed because pnpm found no system CA certificates, so pnpm uses bundled ones there #14777. Imports also failed with "Permission denied" on filesystems that deny hard links and reflinks, and now fall back to copying #14780.pnpm installno longer fails with "Invalid cross-device link" while preserving a package's nestednode_modulesdirectory during a Docker build #14758.pnpm installno longer fails on a package tarball that carries a file at the archive root, such as the._*entries macOStaradds #14701. The file is installed at the root of the package.A
file:tarball packed without the usualpackage/directory is now recorded under the name and version from its ownpackage.json. It was recorded under the alias the dependency was given, at version 0.0.0.Under
nodeLinker: hoisted,pnpm installno longer re-imports packages that are already in place. A repeat install replaced the wholenode_modulestree and reportedPackages: +N. A package is still imported when its directory is missing, when itspackage.jsonno longer carries the installed version, when it is afile:dependency, and when it is patched. Lifecycle scripts no longer run again for a package left in place, andpnpm rebuildand a change toallowBuildsstill reach it.pnpm installnow runs a dependency's build scripts again when its side-effects cache entry has no files to restore #14717. Such builds were skipped and nothing was put in their place, so a script whose whole effect lands outside its own package directory, such as a git hook installer, never took effect. pnpm no longer publishes empty artifacts to the shared side-effects cache either.Resolving and linking dependencies
pnpm install,pnpm add, andpnpm dedupenow applyignoredOptionalDependencies#14729. Matching optional dependencies are left out of the lockfile and are not installed. pnpm 12 installed them whenever it resolved dependencies from scratch.pnpm installno longer links a transitive dependency to a workspace package whenlinkWorkspacePackagesistrueand the dependency is declared with a plain version range #14781. EnablingpreferWorkspacePackagesdoes not change this. SetlinkWorkspacePackages: deepto link them.pnpm installno longer leaves dangling dependency links in workspace packages located above the workspace root #14726.pnpm installandpnpm addno longer leave a dangling symlink innode_moduleswhen a project starts depending directly on a package that the lockfile holds only as a transitive dependency with resolved peer dependencies #14714.pnpm dedupenow keeps a compatible auto-installed peer when another workspace project depends on a newer major #14697. Repeated runs alternated between compatible and incompatible peer versions.pnpm peers checkno longer reports a peer dependency declared asworkspace:^,workspace:~, or a bareworkspace:as unmet #14770. pnpm reported these as unmet whatever version the linked workspace project supplied.Performance
Sped up repeat installs #14540. pnpm checks the store's files only for the packages it links into
node_modules, instead of every package in the lockfile. Creating the command shims innode_modules/.binmakes about 1,500 fewer filesystem calls in a 76 project workspace. Installs that use the global virtual store read their slot paths from the cache directory instead of deriving them every time. Verifying a large lockfile also allocates less memory.Sped up
pnpm installin Cargo workspaces with many member crates. Repeated installs reuse verified Cargo checksum metadata.Installing several packages from the same Git repository and commit now downloads the source once per install #14725. Each package still runs its prepare scripts in its own copy of the checkout.
Running scripts and tasks
pnpm now passes Ctrl+C on to the script or command it started and waits for it to shut down #14723. pnpm exited first, so a script that was still writing landed on the shell prompt.
pnpm run "/pattern/" --no-bailnow lets every matched script finish after one of them fails #14718. The command exits withERR_PNPM_RUN_FAILED, and its message lists the scripts that failed in the order they were selected.pnpm pipelineno longer fails on a project that tracks a symlink, such as aCLAUDE.mdpointing atAGENTS.md#14692. Changing a symlinked input's target invalidates that task's cache, andpnpm pipeline --no-cacheno longer hashes task inputs.Commands
pnpm add -g,pnpm update -g, andpnpm remove -gno longer change global bins or install directories after reading only part of an installed package group #13796. If any declared package manifest is missing, malformed, or unreadable, pnpm now fails before it activates or removes anything and leaves the existing global installation intact.pnpm dedupenow processes every workspace project by default, including workspaces that keep a separate lockfile per project #14732. Workspace filters select which projects it processes, and--fail-if-no-matchexits with an error when no project matches.pnpm update <name>@​<version>now keeps the range operator the manifest declares #14745. Runningpnpm update react@19.3.0on"react": "^19.2.8"writes"react": "^19.3.0". Ajsr:entry keeps itsjsr:prefix, and a plainpnpm updatenow moves ajsr:range the way it moves an npm range.pnpm --filterdirectory selectors now support?wildcards and character classes such as[ab]. A*or?wildcard no longer selects a directory whose name starts with a dot, as on pnpm 11.pnpm deploy --legacynow prefers the dependency versions pinned in the source workspace lockfile when they still satisfy the deployed project's range #13857.pnpm sbomnow leaves out a package's author field when the manifest author name is empty or contains only whitespace #14685. In a filtered or split workspace run, only a project with noauthorfield inherits the workspace root's author.pnpm sbom --sbom-format spdxnow writescreationInfo.createdwith whole seconds, such as2026-09-08T10:38:21Z#14684. The fractional seconds it carried were rejected by strict SPDX consumers.Configuration
The
updateConfigpnpmfile hook now receives the resolved configuration, including settings that came from.npmrc, the command line, or a default #14676. Scoped registries are reported underregistriesByScope, and a hook may rewrite that map to change where packages are fetched from. Registry credentials are reported underconfigByUri, as pnpm 11 reports them. An unset setting is left out rather than reported asnull.pnpm audit --fixand theminimumReleaseAgeStrictapproval prompt now keep the comments inminimumReleaseAgeExcludewhen they append an entry to it inpnpm-workspace.yaml. The rest of the list is left as written, and thetrustPolicyExcludePruneandminimumReleaseAgeExcludePrunecleanups keep the comments of the entries they retain.pnpm installandpnpm dedupenow run those cleanups too #14759. Onlypnpm add,pnpm update, andpnpm removepruned the entries that the freshly written lockfile no longer resolves.pnpm config set --global node-download-mirrorsno longer rejects the key #13611. The global config file already acceptednodeDownloadMirrors, but the command refused to write it.NO_PROXYentries that start with a dot, such as.npmjs.org, now bypass the proxy for the domain and its subdomains #14686.pnpm no longer cr
Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 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 has been generated by Renovate Bot.