PNpM CLI
Minor Changes
-
pnpm can now manage npm, Python, and Cargo dependencies in the same workspace. Enable
python.enabledorcargo.enabledinpnpm-workspace.yaml, then usepnpm installto install them together.- Add Python packages with
pnpm add pypi:<package>. pnpm usespyproject.toml,pylock.toml, and a managed.venv. Frozen and offline installs are supported, andpnpm runandpnpm execmake the environment's executables available #14566. - Add Rust crates with
pnpm add crate:<package>. pnpm supports crates.io and custom sparse registries configured withcargo.indexUrl. Registry authentication supports pnpm credentials and, for crates.io,CARGO_REGISTRY_TOKENor$CARGO_HOME/credentials.toml.
Both ecosystems support faster dependency resolution through
pnprServer, with local resolution as a fallback when the server does not support it. - Add Python packages with
-
Added
pnpm pipeline [name]to install frozen dependencies and run workspace tasks declared inpipelines. It selects affected projects, runs their task graph, and continues running tasks after a task fails.Tasks support
inputs,outputs,env, andcachesettings. Cached results restore task outputs and replay logs. Cargo tasks can reuse local build state between worktrees withtasks.<name>.cargoTargetDir. SetincludeWorkspaceRoot: trueto include root tasks.Use
pnpm pipeline --dry-runto preview the task graph without installing configuration dependencies or running workspace hooks. -
Added support for Android on arm64 and x64, FreeBSD on x64, and Linux on ppc64le, s390x, and RISC-V (riscv64 with glibc) #14431, #14597, #7582.
-
Added
trustPolicyExcludePruneto automatically remove unused versions and packages fromtrustPolicyExcludewhen runningpnpm add,pnpm update, orpnpm remove. It is disabled by default. Package name patterns such as@scope/*are kept, and cleanup is skipped whensharedWorkspaceLockfileisfalse. -
Added
pnpm change checkfor CI validation of package versions against theversioning.epicsbands andversioning.fixedgroups inpnpm-workspace.yaml. It reports all violations, including packages that are not part of the current release.
Patch Changes
-
Registry metadata is now kept separate for registries with different URL paths or schemes. This prevents installs from using another registry's package versions or tarball URLs, and keeps metadata fetched over HTTP from being reused for HTTPS #13558.
The first install after upgrading refetches registry metadata. The package store is unchanged.
pnpm cache viewnow shows full registry URLs. Scripts that parse the directory names frompnpm cache list-registriesorpnpm cache listneed updating. -
Patches that add build scripts or a
binding.gypnow trigger a build, subject to build approval. Unapproved builds appear under "Ignored build scripts" #14648. -
Build scripts can now be rejected before installing a package with
pnpm add --allow-build=!<pkg>, including global installs.pnpm approve-builds <pkg>andpnpm approve-builds !<pkg>also save decisions when no packages are awaiting approval. They warn if the named package is not awaiting approval #14067. -
A registry configured in
.npmrcnow takes precedence over registry settings saved bypnpm loginin the globalconfig.yaml. This fixes installs using the wrong registry after login #14614. -
Large downloads over slow connections no longer time out while data is still arriving.
fetch-timeoutnow limits how long a request can go without making progress #14604. -
Sped up installs in workspaces with many projects when reusing a warm global virtual store #14540.
-
pnpm deployis faster in large workspaces and no longer fails withERR_PNPM_LOCKFILE_CONFIG_MISMATCHwhen the project includes a.pnpmfile.mjs#14539, #14671. -
pnpm add --workspace <pkg>works again. It saves the dependency with theworkspace:protocol and links it from the workspace. The command fails if no workspace project provides the package #14602. -
pnpm addandpnpm installnow accept protocol-prefixed selectors such asjsr:@scope/pkg,npm:pkg@^1.0.0, andworkspace:pkg@*#14590. Installs with JSR dependencies in the lockfile also no longer fail withERR_PNPM_META_FETCH_FAIL#14649. -
Boolean flags now accept explicit inline values. For example,
pnpm install --prod=falseinstalls devDependencies, while--prod=trueskips them #14553. -
pnpm install <pkg>now accepts--offlineand--prefer-offline, aspnpm add <pkg>already did #14194. -
Fixed
pnpm install --frozen-lockfilerejecting a freshly generated lockfile when overrides use relativefile:orlink:paths in a workspace #14555. -
Fixed installs with config dependencies failing on symlinked lockfiles, such as those used by Bazel and Nix, when the config dependencies have not changed. Updates that would write through a symlink remain disallowed. Updating config dependencies also preserves lockfiles that start with a byte order mark #14372.
-
Fixed package manager version pins being written to the wrong lockfile when
lockfileDiris set. The pins also remain consistent across commands when version switching is disabled, avoiding unnecessary lockfile changes #14633, #14575. -
pnpm importnow respectslockfileDirand branch lockfiles without modifying other lockfiles. Failed imports restore the destination lockfile #14563. -
pnpm patch-commitnow produces valid patches when files are added or deleted.pnpm installalso accepts patches that delete files without listing their contents, and patch files with CRLF line endings #14559, #14557. -
Fixed version ranges with partial upper bounds. For example,
<=16now includes all 16.x versions, and>=0.11 <=3correctly accepts 3.0.1 #14419. -
Workspace package patterns now support
.and..segments and repeated slashes. Patterns such as./packages/*and exclusions such as!./packages/foonow match correctly #14571. -
packageConfigssettings now apply to the specified projects whensharedWorkspaceLockfileisfalse, includingoverrides,hoist,modulesDir,saveExact, andsavePrefix. Workspaces with a shared lockfile report which entries were ignored #14556. -
pnpm runandpnpm execno longer report a changed workspace structure after a successful install whensharedWorkspaceLockfileisfalseandverifyDepsBeforeRunis enabled #14588. -
Commands run from a project's subdirectory now find the nearest ancestor with a manifest. This fixes commands such as
pnpm binreturning paths under the wrong directory.pnpm initstill creates its manifest in the current directory, andpnpm execstill runs there #14622. -
Relative
scriptShellpaths inpnpm-workspace.yamlnow resolve from the workspace root, including when scripts run in nested packages. Bare command names such asbashstill usePATH#14422. -
Fixed installing the pnpm version pinned in
packageManagerwhennodeLinkerishoisted. Managed Node.js, Deno, and Bun installations also work when the global config usesnodeLinker: hoisted#14595. -
The JavaScript pnpm can again switch to a project's pinned pnpm version on platforms without a native binary for that version, such as Alpine Linux with pnpm 10 or Intel Macs with pnpm 11. If a native pnpm version does not support the platform, the error now names the missing target #13622.
-
Provisioning Yarn 6 now uses
GH_TOKENorGITHUB_TOKENwhen available to avoid GitHub's anonymous API rate limit in CI. Tokens are only sent whenstrict-sslis enabled. -
Fixed concurrent installs sharing a global virtual store on macOS failing with "failed to import ... No such file or directory" #14560.
-
Fixed
pnpm setupfailing withERR_PNPM_DIRECTORY_FETCHER_PATH_ESCAPEon Windows. Localfile:dependencies whose directories are symlinks or junctions are now packed correctly #14618. -
On Windows, installs now retry replacing command shims temporarily locked by another process #14549.
-
Fixed argument forwarding on Windows with
shellEmulatorenabled. Paths ending in a backslash, line breaks, and literal shell expressions are preserved #14548. -
Windows store paths now consistently use backslashes in
pnpm store pathoutput and in thestoreDirandvirtualStoreDirfields ofnode_modules/.modules.yaml. -
Invalid certificates in
caorcafileno longer cause anInvalid CA certificateerror. Valid certificates still apply, and blankcertorkeyvalues are treated as unset #14646. -
Installs now respect the archive extraction concurrency limit even after a download is abandoned #14585.
-
pnpm auditsummaries now exclude advisories ignored throughauditConfig.ignoreGhsasand report them separately. When all advisories are ignored, the summary says so #14535. -
pnpm pack --jsonnow reports errors as JSON. Lifecycle script output appears before the final JSON output. -
pnpm outdated -rnow wraps theDependentscolumn, keeping the table readable when many workspace projects use the same dependency #14591. -
Shell completions now support the
pnalias in bash, fish, pwsh, and zsh #11955. -
pnpm versionnow accepts-mas a short alias for--message#14567.
<!-- sponsors -->
Platinum Sponsors
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a> </td> <td align="center" valign="middle"> <a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/openai_dark.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/openai_light.svg" /> <img src="https://pnpm.io/img/users/openai_dark.svg" width="160" alt="OpenAI" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://notion.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion"></a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <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> </tbody> </table>
Gold Sponsors
<table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <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" rel="noopener noreferrer"> <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" rel="noopener noreferrer"><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" rel="noopener noreferrer"> <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://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <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> <td align="center" valign="middle"> <a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <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://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <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> <td align="center" valign="middle"> <a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a> </td> </tr> </tbody> </table>
<!-- sponsors end -->