pnpm 12 RC 0
- Running pnpm setup, pnpm self-update, or a command that modifies the global installation through sudo now fails with ERR_PNPM_SUDO_NOT_SUPPORTED instead of silently operating on the root user's home directory
- pnpm fetch and any install run with virtualStoreOnly no longer writes a .pnp.cjs loader under nodeLinker: pnp
- When no directory above the project accepts a hard link, the default store is now created at <project>/node_modules/.pnpm-store instead of in the pnpm home directory
- Archive entries whose paths use backslash as a separator are now read the same way pnpm reads them, with nested paths like bin\tool.js resolving to bin/tool.js and path traversals with backslashes being rejected
- Fixed file: dependencies not being re-copied when their source directory changed
- Write blocked-build approval scaffolding to the discovered workspace manifest when using per-project lockfiles
- Concurrent installs sharing a global virtual store no longer fail with failed to remove existing directory error and no longer briefly remove a package directory another process is reading
- Fixed link: dependencies under enableGlobalVirtualStore so linked children are materialized and slots remain isolated by their resolved link targets
- A headless install with --frozen-lockfile now creates the command shims for a publicly hoisted workspace package's bin
- Prevent pnpm from removing project files when modulesDir resolves to the project root
- Fixed pnpm install ignoring a pnpm-lock.yaml that carries a leading env lockfile document when the file has CRLF line endings or a UTF-8 byte order mark
- A stray non-directory entry in node_modules no longer fails an install and is skipped instead
Minor Changes
- 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.
Patch Changes
-
Archive entries whose paths use
\as a separator are now read the same way pnpm reads them. A nested path spelledbin\tool.jsby Windows publishing tooling resolves tobin/tool.js, and a path traversal spelled with backslashes is rejected instead of being stored verbatim. -
Fixed
file:dependencies not being re-copied when their source directory changed. Afile:dependency is copied into the store at install time rather than symlinked, so editing the local package's files and runningpnpm installagain left the previous copy in place — the lockfile is unchanged by such an edit, so the install treated the tree as up to date. -
Write blocked-build approval scaffolding to the discovered workspace manifest when using per-project lockfiles.
-
Concurrent installs sharing a global virtual store no longer fail with
failed to remove existing directory ... prior to swap: Directory not empty, and no longer briefly remove a package directory another process is reading. -
Fixed
link:dependencies underenableGlobalVirtualStoreso linked children are materialized and slots remain isolated by their resolved link targets. -
A headless install (
--frozen-lockfile) now creates the command shims for a publicly hoisted workspace package'sbin, matching what a normal install already did and what pnpm's own headless install does. Previously those shims were missing until the next non-frozen install. -
pnpm fetch, and any install run withvirtualStoreOnly, no longer writes a.pnp.cjsloader undernodeLinker: pnp. These installs populate the virtual store without linking the project, so the loader would have claimed the project resolves out of a store it was never linked into. The importer links andnode_modules/.package-map.jsonwere already skipped; the PnP loader now follows the same rule. -
Prevent pnpm from removing project files when
modulesDirresolves to the project root. -
Fixed
pnpm installignoring apnpm-lock.yamlthat carries a leading env lockfile document when the file has CRLF line endings or a UTF-8 byte order mark, as acore.autocrlfcheckout on Windows produces. The lockfile was reported as broken withmultiple YAML documents detectedand every dependency was re-resolved from the registry #13606. -
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. -
A stray non-directory entry in
node_modulesno longer fails an install. Files placed next to the installed dependencies are skipped rather than reported as an unreadable manifest.