Packages

pnpm

12.14.0MIT
  • 12.14.0 is the latest, published 15 October 2026.
  • 32 security advisories, all fixed.
  • 12.x: 30 releases since 26 August 2026, 30 in the last 90 days.

Security advisories

Grouped by the version that fixes them, so one upgrade reads as one step.

11 older fixes

Releases in the last 90 days

Feed of releases and advisories

Every stable release, newest first. Notes are quoted as the maintainers published them.

  1. 12.14.0

    15 October 2026
    --registry, --https-proxy, --http-proxy, and --no-proxy now apply when pnpm resolves and downloads the pnpm version a project pins in packageManager. Before, these lookups went to https://registry.npmjs.org/, which a firewall that only allows a private registry blocks #16911.

    Section of a shared release note

    Setting up pnpm and toolchains

    • --registry, --https-proxy, --http-proxy, and --no-proxy now apply when pnpm resolves and downloads the pnpm version a project pins in packageManager. Before, these lookups went to https://registry.npmjs.org/, which a firewall that only allows a private registry blocks #16911.

    • On Windows, pnpm install now installs the Rust toolchain for rustup's default host, so a machine set up with rustup set default-host x86_64-pc-windows-gnu gets the MinGW toolchain. Without a default host, pnpm installs the MSVC toolchain for the machine's architecture, as rustup does. This includes a pnpm built for MinGW, such as the MSYS2 package, which has installed the MinGW toolchain since 12.13.0. An x64 pnpm on ARM64 Windows now installs the ARM64 toolchain #16854.

  2. 11.28.6

    15 October 2026
    Pnpm now relinks the bins of a pnpm version it installed earlier for packageManager or pnpm with. A pnpm 12 version installed by a pnpm release older than 11.28.4 could keep a launcher that ran node on the native binary, so every command failed with SyntaxError: Invalid or unexpected token #16646.

    Section of a shared release note

    Setting up pnpm

    • pnpm now relinks the bins of a pnpm version it installed earlier for packageManager or pnpm with. A pnpm 12 version installed by a pnpm release older than 11.28.4 could keep a launcher that ran node on the native binary, so every command failed with SyntaxError: Invalid or unexpected token #16646.

    • pnpm setup no longer tries to install pnpm globally from npm's bin directory when pnpm was installed with npm. It printed Failed to create bin at <PNPM_HOME>/bin/pnpm #16855.

  3. 12.13.0

    13 October 2026
    Pnpm setup now works when pnpm was installed with npm on macOS. It installed pnpm from npm's bin directory and left a $PNPM_HOME/bin/pnpm that could not run #16855.

    Section of a shared release note

    Setting up pnpm

    • pnpm setup now works when pnpm was installed with npm on macOS. It installed pnpm from npm's bin directory and left a $PNPM_HOME/bin/pnpm that could not run #16855.

    • pnpm runs again after pnpm setup when globalShims enables pnpm. Every command failed with "the global target of the pnpm shim points back at the shim" #16874.

    • A pnpm built for the MinGW target on Windows, such as the MSYS2 package, now installs the MinGW Rust toolchain that rust-toolchain.toml names. It used to install the MSVC toolchain.

  4. 10.34.7

    12 October 2026
    : Switching to the pnpm version in packageManager now works through registry mirrors that strip npm's signatures or re-sign packages with their own key. pnpm then reads the signature from https://registry.npmjs.org/ and verifies it against the integrity of the downloaded pnpm #16778.

    Patch Changes

    • 97f550c: Switching to the pnpm version in packageManager now works through registry mirrors that strip npm's signatures or re-sign packages with their own key. pnpm then reads the signature from https://registry.npmjs.org/ and verifies it against the integrity of the downloaded pnpm #16778.

    • b11d7bb: The update notification now suggests the standalone install script instead of pnpm self-update when PNPM_HOME is not set, such as when another package manager installed pnpm. pnpm self-update installs into PNPM_HOME, so in that case it cannot replace the pnpm in use.

  5. 12.12.1

    11 October 2026
    This release adds OIDC authentication to pnpm dist-tag and the tool: protocol. pnpm publish now checks which registry an NPM_ID_TOKEN was issued for before using it.

    This release adds OIDC authentication to pnpm dist-tag and the tool: protocol. pnpm publish now checks which registry an NPM_ID_TOKEN was issued for before using it.

    Patch Changes

    • pnpm publish now uses an NPM_ID_TOKEN only if its aud claim matches the selected registry, such as npm:registry.npmjs.org. A token for another registry is skipped with a warning, and pnpm falls back to the configured credentials.

    • pnpm dist-tag add, rm, and ls now support OIDC authentication in CI. Enable "Allow npm dist-tag" in the package's trusted publishing settings to manage tags without a stored npm token.

    • Added the tool: protocol for the tools pnpm downloads itself: Node.js, Bun, Deno, and Yarn. pnpm add bun@tool:1.3.0, pnx node@tool:22, and pnx yarn@tool:4 work like the runtime: spelling, which stays supported as an alias. A lockfile written for runtime: stays up to date when package.json switches to tool:, and the other way around.

      A named registry can no longer be called tool.

  6. 12.12.0

    10 October 2026
    This release shares task results and dependency builds through a remote cache, adds the addMissingPeerTypes setting, and lets pnpm add --config and pnpm update manage configuration dependencies. It also fixes dangerouslyAllowAllBuilds running the build scripts of packages that allowBuilds denies.

    This release shares task results and dependency builds through a remote cache, adds the addMissingPeerTypes setting, and lets pnpm add --config and pnpm update manage configuration dependencies. It also fixes dangerouslyAllowAllBuilds running the build scripts of packages that allowBuilds denies.

    Minor Changes

    • pnpm pipeline can share task results between machines. A result is a signed artifact stored on a pnpr server or on a server that speaks the Turborepo Remote Cache API, such as Vercel Remote Cache.

      The remote side-effects cache can also store dependency builds on a Turborepo Remote Cache server. Both caches read the new remoteCache setting, which names the server and holds the signing keys. pnpm pipeline --report records the run under the organization remoteCache.org names.

    • Added the addMissingPeerTypes setting, which links the @types package of a peer dependency next to every package that peer-depends on it. For example, a package that peer-depends on react gets the project's @types/react linked next to it. This lets TypeScript find the types of a peer dependency when the global virtual store is on #15689.

    • pnpm add --config and pnpm update now handle configuration dependencies the way they handle other dependencies #16814.

      pnpm add --config saves a version range in pnpm-workspace.yaml by the same rules as pnpm add, so pnpm add --config my-config@latest saves a range such as ^1.2.0. It also resolves the package again when pnpm-lock.yaml already locks an older version.

      pnpm update updates configuration dependencies within their ranges, and pnpm update --latest moves them to their latest version. A selector such as pnpm update my-config updates only the configuration dependencies it names.

    Patch Changes

    • A package set to false in allowBuilds no longer runs its build scripts when dangerouslyAllowAllBuilds is true. The two settings together now allow every build except the denied ones. Previously, dangerouslyAllowAllBuilds ignored the denials.

    • pnpm now switches to the pnpm version a project pins even when it cannot read its configuration. Previously, a setting it rejected in the global config file, an .npmrc file, or _auth, or a pnpm-workspace.yaml it could not parse, stopped every command, pnpm --version included.

    • pnpm update and pnpm why accept --depth Infinity again. They failed with invalid value 'Infinity' for '--depth <DEPTH>' #16817.

    • pnpm deploy without injectWorkspacePackages now binds a peer dependency of a linked workspace package to the version its parent provides, as an injected install does. Previously the deploy failed with ERR_PNPM_DEPLOY_AMBIGUOUS_PEER whenever other packages in the deployed graph depended on different versions of that peer #16807.

    • pnpm deploy --legacy no longer fails with ERR_PNPM_SPEC_NOT_SUPPORTED_BY_ANY_RESOLVER when a workspace dependency of the deployed project declares a workspace: peer dependency that the project does not depend on itself. pnpm now copies that peer from the workspace into the deploy directory.

      An auto-installed peer declared with workspace: now always resolves to the workspace project. Previously, workspace:* and workspace:^1.0.0 peers could be installed from the registry #16806.

    • Repeat installs no longer resolve again when an injected workspace package lists a dependency also as a peer dependency.

    • Sped up frozen installs of unchanged injected workspace packages that use hardlinks.

    • Sped up workspace discovery with subtree exclusions such as !generated/**.

    • A key under a registry URL in the _auth setting that does not start with @ is now skipped with a warning, so a field a later pnpm version adds there no longer breaks this one. A key that holds an authToken object but lacks its @, such as org for @org, is still an error.

  7. 12.11.2

    9 October 2026
    This release fixes --workspace-concurrency=Infinity, filters set by an updateConfig hook, and store fetches with enable-modules-dir=false.

    This release fixes --workspace-concurrency=Infinity, filters set by an updateConfig hook, and store fetches with enable-modules-dir=false.

    Patch Changes

    • --workspace-concurrency=Infinity now runs workspace projects with no concurrency limit. It used to fail with invalid digit found in string #16793.

    • pnpm install and other recursive commands now apply the filter and filterProd that an updateConfig hook sets. They used to run on every workspace project #16792.

    • enable-modules-dir=false now also fetches the packages an install reuses from an existing lockfile, so the store holds every package the lockfile lists.

  8. 12.11.1

    9 October 2026
    This release fixes two ways pnpm install could fail, runs tools of any Rust release through pnx, and treats registry.npmjs.com as an alias of the npm registry.

    This release fixes two ways pnpm install could fail, runs tools of any Rust release through pnx, and treats registry.npmjs.com as an alias of the npm registry.

    Patch Changes

    • pnpm install no longer fails when packageManager pins the pnpm version that is already running and the registry does not publish that version. pnpm warns and continues. A registry mirror that has not synced a release no longer blocks the commands of a project pinned to it.

    • pnpm install no longer fails with ERR_PNPM_CMD_SHIM_CHMOD when node_modules/.bin holds a shim that another user created, if everyone can already execute it and it is not world-writable. This happens when several users share one checkout.

    • enable-modules-dir=false (enableModulesDir: false through the Node.js addon) fetches the registry packages the host can install into the store again, as pnpm v10 did, while still writing nothing under node_modules. The setting exists for a node_modules that something else mounts from the store, such as a FUSE daemon, and that consumer no longer has to download each package on first access. A plain --lockfile-only run still fetches nothing.

    • pnpm pack and pnpm publish no longer put .npmignore and .gitignore files in the tarball. A files entry that names one still ships it.

    • pnpm now treats https://registry.npmjs.com/ as an alias of https://registry.npmjs.org/. Registry requests, credentials, and trusted publishing use the canonical hostname.

    • pnx --package=rust@<channel> <tool> runs a tool of that Rust release, for example pnx --package=rust@nightly-2026-01-01 cargo build. pnpm installs the release with the components and targets from rust-toolchain.toml and the target of each --target argument.

    • pnpm install now links agent skills for more coding agents. It detects the agent from ANTIGRAVITY_AGENT, COPILOT_AGENT, COPILOT_CLI, CODEX_THREAD_ID, CODEX_SANDBOX, AI_AGENT, and CLAUDE_CODE pnpm/tasks#116.

    • When the registry rejects pnpm stage publish, the error message now starts with "Failed to stage package".

  9. 12.11.0

    9 October 2026
    This release adds Rust toolchain management, links the agent skills that dependencies ship, adds the permissions setting, and keeps the colors of streamed script output.

    This release adds Rust toolchain management, links the agent skills that dependencies ship, adds the permissions setting, and keeps the colors of streamed script output.

    Minor Changes

    • pnpm install now links the agent skills that direct dependencies ship under skills/<name>/SKILL.md into the project's agent skill directories, such as .claude/skills. A package's skills are linked only after you approve them with pnpm approve. The skills.dirs setting chooses the directories pnpm/rfcs#35.

      Added the permissions setting, which records what each dependency may do. Its build capability works like allowBuilds and takes precedence over it. pnpm approve-builds writes to permissions when pnpm-workspace.yaml already has it, and to allowBuilds otherwise.

      Added pnpm permissions, which lists the granted and denied permissions and the packages awaiting approval. pnpm approve reviews build scripts and agent skills in one prompt pnpm/rfcs#36.

    • pnpm now installs and runs Rust toolchains.

      • With cargo.enabled, pnpm install installs the toolchain named in rust-toolchain.toml. pnpm verifies the release signature, stores the toolchain once per machine, and links it into .pnpm/rust. pnpm run and pnpm exec put its cargo and rustc on the PATH.

      • pnpm add -g rust@<channel> installs a toolchain globally. The cargo and rustc commands run it outside projects that pin their own. pnpm update -g, pnpm ls -g, and pnpm remove -g manage it like any global package.

      • In a project, pnpm add rust@<channel> pins the toolchain in rust-toolchain.toml.

      • pnpm shim add rust adds project-aware shims for cargo, rustc, and the other Rust tools. In a project with a rust-toolchain.toml, they run the toolchain the file names and install it on first use. Elsewhere, the next command of the same name on PATH runs, such as rustup's.

    • pnpm run and pnpm exec now keep the colors of script output that they print under the project's name, such as with --stream. pnpm sets FORCE_COLOR=1 for these scripts when its own output is in color, unless FORCE_COLOR is already set.

      Script output is also rendered more cleanly:

      • A line that a progress bar redraws with \r shows only its last state.

      • Escape codes that move the cursor or clear the screen are dropped.

      • Long colored lines are cut at the terminal width.

      • pnpm -r run no longer garbles its live output when a script fails while other scripts are still running.

    Patch Changes

    Installing packages

    • pnpm no longer panics with "unexpected error when polling the I/O driver" when it runs under QEMU user-mode emulation, such as a linux/amd64 container on an Apple Silicon Mac #16696.

    • pnpm view, pnpm update, and other commands that read registry metadata now work behind proxies that end a response by closing the connection without a TLS close_notify alert #16704.

    • pnpm now switches to the version a project pins in packageManager or devEngines.packageManager even when pnpm-workspace.yaml has a setting the running pnpm cannot read, such as a lockfile.includeResolutionSettings section. If pnpm does not switch, it still reports that setting #16675.

    • When the pnpm package has to download its native binary on first run, it now uses the registry and credentials from .npmrc and from the npm_config_registry and pnpm_config_registry environment variables. COREPACK_NPM_REGISTRY still takes precedence. A project .npmrc is not read when COREPACK_INTEGRITY_KEYS turns off the signature check #16655.

    • pnpm install and pnpm add --config now apply minimumReleaseAge when they resolve a config dependency. A config dependency range resolves to the newest version that is old enough, so a later clean pnpm install --frozen-lockfile accepts the lockfile #16660.

    • pnpm remove with catalogPrune no longer removes catalog entries that pnpm-lock.yaml still records for workspace projects missing from disk. Before, a following frozen install failed with ERR_PNPM_LOCKFILE_CONFIG_MISMATCH #16679.

    • With cargo.enabled, pnpm install now writes the source replacement for vendored crates into .pnpm/crates/config.toml and includes it as optional from .cargo/config.toml. A checkout without .pnpm builds with plain Cargo #16659.

    • With nodeLinker.type set to loaded, Node.js now stops with ERR_PNPM_LOADER_UNSUPPORTED_NODE when it preloads the store loader on a version the loader cannot serve. The supported versions are ^24.18.0 || >=26.2.0. On other versions, CommonJS packages imported from ESM failed with Cannot find module on their first relative require().

    • On Windows, pnpm install no longer fails with "The filename, directory name, or volume label syntax is incorrect" when a package contains a file whose name is invalid on Windows, such as icon.svg?as=metadata.d.ts. pnpm removes the invalid characters from the name and prints a warning that lists the renamed files.

    • On Windows, hoisting no longer fails intermittently with link errors when a junction is created or replaced concurrently pnpm/tasks#53.

    Resolving dependencies

    • pnpm install --no-optional now installs the peer dependencies a project declares when autoInstallPeers is on. The lockfile marked such a peer optional: true when another dependency had it as an optional peer.

    • pnpm install and pnpm dedupe now link an optional peer to the workspace package that the workspace root depends on when the picked version matches it. They installed the registry package with the same name and version #16706.

    • Removal overrides such as "debug>supports-color": "-" now also apply to an optional peer that a package declares only in peerDependenciesMeta #16681.

    • pnpm add and other installs that re-resolve dependencies now keep the locked devEngines.runtime version while it still satisfies the declared range #16764.

  10. 12.10.1

    6 October 2026
    This release fixes pnpm install failures after an overrides change and on a filtered frozen install with catalogPrune. It also fixes several bugs in the experimental nodeLinker.type: loaded, which now keeps its generated files in node_modules.

    This release fixes pnpm install failures after an overrides change and on a filtered frozen install with catalogPrune. It also fixes several bugs in the experimental nodeLinker.type: loaded, which now keeps its generated files in node_modules.

    Patch Changes

    • With nodeLinker.type: loaded, pnpm now writes its generated files to node_modules, which projects already ignore in git. The store manifest and loader are node_modules/.pnpm/.store-manifest.json and node_modules/.pnpm/.store-loader.mjs. Bin shims are in node_modules/.bin.

      Earlier versions wrote .pnpm-store.json and .pnpm-store-loader.mjs to the project root, and a .pnpm directory to the root and to each workspace package. Delete them after reinstalling.

    • With nodeLinker.type: loaded, packages that ship their own node_modules directory, such as npm with its bundled dependencies, now load from the store. Before, one such package in the install stopped every Node.js process from starting.

    • With nodeLinker.type: loaded, scripts can now run a Node.js runtime installed through devEngines.runtime. Before, every script that called node re-ran its own shim until it failed with "Argument list too long".

    • With nodeLinker.type: loaded, Node.js processes start faster. In a project with 13,000 stored files, the startup overhead per process dropped from 67 ms to 18 ms.

    • pnpm install no longer fails with ERR_PNPM_NO_MATCHING_VERSION after a change to overrides when the lockfile resolves an optional peer dependency to an npm alias of another package #16654.

    • A frozen install with catalogPrune no longer removes catalog entries that pnpm-lock.yaml still records. Before, pnpm install --frozen-lockfile --filter failed with ERR_PNPM_LOCKFILE_CONFIG_MISMATCH when some workspace projects were missing from disk #16638.

    • pnpm install --fix-lockfile no longer removes the deprecated and hasBin fields from lockfile entries #6600.

    • With enableGlobalVirtualStore, an install that updates node_modules now repairs a package in the global virtual store that an interrupted install left without some of its dependency links or package files. Before, such an install kept the incomplete package if the project's node_modules already recorded it #16642.

    • pnpm install now skips the Cargo and Python projects inside a nested directory that has its own pnpm-workspace.yaml or .git directory, such as a git worktree of the same workspace or a separate clone.

    • The Request took warning for package metadata now starts timing when pnpm sends the request. Before, it also counted the time the request waited for a free request slot, so large installs printed it for requests the registry answered quickly.

Show 20 earlier releases
  1. 12.10.0

    6 October 2026
    Pnpm config get --global and pnpm config list --global now show only the global configuration, also when run inside a project. Settings from the project's pnpm-workspace.yaml and .npmrc were included before. The same applies to --location=global #16598.

    Section of a shared release note

    Configuration, setup, and pnpm versions

    • pnpm config get --global and pnpm config list --global now show only the global configuration, also when run inside a project. Settings from the project's pnpm-workspace.yaml and .npmrc were included before. The same applies to --location=global #16598.

    • pnpm now prints config warnings, such as an unset environment variable in .npmrc, when loading the config fails.

    • pnpm 11 releases older than 11.28.4 can run pnpm 12 again when the packageManager field pins it. Since 12.9.0 they failed with SyntaxError: Invalid or unexpected token #16594.

    • On Windows, pnpm self-update no longer runs the update a second time when it replaces a pnpm.cmd linked by pnpm 12.8 or older. cmd.exe read on in the replaced pnpm.cmd, printed an error about a command that is not recognized, and ran the new pnpm once more #16573.

    • pnpm setup now puts $PNPM_HOME/bin first on PATH in login shells that inherited it further down, such as the VS Code terminal on macOS. Before, another node took precedence over the one installed by pnpm runtime set node -g. Run pnpm setup again to update the block in your shell config #16635.

    • pnpm setup now names the shell config file even if it is already up to date #16608.

  2. 11.28.5

    6 October 2026
    This release reads cached registry metadata faster and makes pnpm config get --global ignore project settings. It also carries several security fixes for package archives, git dependencies, and config dependencies.

    This release reads cached registry metadata faster and makes pnpm config get --global ignore project settings. It also carries several security fixes for package archives, git dependencies, and config dependencies.

    Patch Changes

    Security

    • security

      pnpm now verifies locked config dependencies against their registry before installing them. Config dependencies must come from an npm registry. The lockfile can no longer replace the integrity of a config dependency pinned with version+integrity.

    • security

      Lockfile verification now checks the tarballs inside a variations resolution against the registry. A name@version lockfile entry with an empty variations resolution is now rejected.

    • security

      pnpm audit signatures now verifies signatures against the integrity recorded in the lockfile. Packages without a recorded integrity cannot pass signature verification.

    • security

      pnpm now rejects a git dependency whose lockfile repository is empty, begins with -, or contains a null byte. Git can no longer read such a value as a command-line option pnpm/tasks#84.

    • security

      A git dependency with a #path: subpath can no longer reach files outside the repository through a symlink in the subpath.

    • security

      pnpm pack, pnpm publish, and installs of git and local directory dependencies now leave out files that a directory symlink or a bundleDependencies entry points to outside the package directory pnpm/tasks#83 pnpm/tasks#93.

    • security

      pnpm deploy with deployAllFiles now rejects symlinks that point outside the package directory. Local package installs with this setting apply the same check.

    • security

      pnpm no longer hangs on a package archive with a negative PAX record length or an entry of 4 GiB or more pnpm/tasks#78 pnpm/tasks#79.

    • security

      Large package downloads and large files inside gzip and bzip2 package archives now use bounded memory during installation. Package manifests and archive metadata larger than 64 MiB are rejected. pnpm publish also rejects manifests and README files larger than 64 MiB in pre-built tarballs before reading them into memory.

    • security

      Two URL or local path dependencies no longer share a virtual store directory when one URL has +, #, :, or ? where the other has /. Such dependencies, including git dependencies pinned with #, now get a hash suffix on their directory name.

    • security

      pnpm licenses now removes terminal control characters from package metadata in table output.

    • security

      The warnings about ignored project .npmrc registry and auth settings no longer print the username and password of a URL-scoped key such as //user:password@registry.example.com/:_authToken.

    Installing and resolving dependencies

    • Dependency resolution reads cached registry metadata faster. The metadata cache moved to <cache-dir>/v12/, so the first install after upgrading downloads registry metadata again. A damaged cache entry is downloaded again, or reported as an error when --offline is set #13512.

    • pnpm install now fails with ERR_PNPM_UNSUPPORTED_PROTOCOL when a dependency uses a specifier with a protocol pnpm does not support, such as Yarn's patch:. pnpm linked such a dependency to a directory that does not exist #16590.

    • When a dependency moves an exact dependency of its own to an older version, a peer dependency that pnpm installed automatically now moves with it. Before, pnpm install and pnpm dedupe kept the newer locked version of the peer, so the lockfile held two copies of it, for example two copies of vue pnpm/tasks#61.

    • pnpm add and pnpm install now keep the peer dependencies that pnpm-lock.yaml records for a package they did not update. A registry whose metadata disagrees with the package's package.json, for example by omitting peerDependenciesMeta, made pnpm add and pnpm dedupe write different lockfiles, so pnpm dedupe --check failed after pnpm add #16615.

    Configuration

    • pnpm config get and pnpm config list with --global or --location=global now show only the global configuration. Both flags included the project's .npmrc before. --location=global also included the project's pnpm-workspace.yaml. pnpm config get --global failed when the global bin directory was not in PATH #16598.

    • pnpm now prints config warnings, such as an unset environment variable in .npmrc, when loading the config fails.

    • pnpm now fails when httpProxy or httpsProxy in pnpm-workspace.yaml or the global configuration is not a string.

    • pnpm dlx now uses the release entry of nodeDownloadMirrors from the workspace configuration when downloading Node.js runtimes #11281. Mirrors for other channels, such as rc and nightly, still apply only from the global configuration.

    Commands

    • pnpm run and pnpm exec now forward --config.* command-line flags to the install started by verifyDepsBeforeRun pnpm/tasks#60.

    • pnpm dlx with --package but no command now fails with 'pnpm dlx' requires a command to run. Before, it installed the package and then crashed trying to run an empty command.

    • pnpm unpublish <pkg>@<version> now deletes the tarball under the registry's path when the registry is served under one, such as Gitea's npm registry. It used to send the delete to the host root and report success without removing the version #16568. It also no longer mistakes a sibling path such as /npm-mirror/ for the registry path /npm/ pnpm/tasks#94.

    • The interactive pnpm audit --fix picker now shows each patched version with the saveExact and savePrefix style that the override is written with #13209.

  3. 12.9.1

    3 October 2026
    This release moves the WebContainer build into a separate @pnpm/wasm package, shrinks the pnpm package back to about 4 MB, and fixes pnpm publish with provenance from GitLab CI.

    This release moves the WebContainer build into a separate @pnpm/wasm package, shrinks the pnpm package back to about 4 MB, and fixes pnpm publish with provenance from GitLab CI.

    Patch Changes

    • The WebAssembly build for StackBlitz WebContainers now ships as a separate @pnpm/wasm package. The pnpm and @pnpm/exe packages no longer include it, which brings their unpacked size back from about 55 MB to about 4 MB. In a WebContainer, install @pnpm/wasm with npm to get the pnpm command.

    • pnpm publish with provenance from GitLab CI is no longer rejected by the npm registry with a 422 error. The provenance statement now includes the GitLab CI variables in invocation.parameters, as npm does #16551.

    • pnpm audit signatures now uses the TLS settings of the redirect target when a registry redirects its signing-keys request, for example to registry.npmjs.org. A cafile scoped to a private registry no longer makes the redirected request fail #16541.

    • Fixed pnpm install --frozen-lockfile rejecting an up-to-date lockfile when an injected workspace package uses a catalog entry in peerDependencies #16557.

    • The [<since>] filter selector works again with Git 2.24 through 2.27 #16561. With Git older than 2.24, the selector now fails with an error that names the required Git version.

      It also detects changes in projects whose directory names contain non-ASCII characters. Such a change used to be credited to the parent project. changedFilesIgnorePattern and testPattern now match changed files whose names contain non-ASCII characters.

    • The pnpm executable is about 10% smaller. On macOS arm64 it went from 45.1 MB to 40.3 MB.

    • Sped up trust downgrade checks for packages with long release histories.

    • With optimisticRepeatInstall: false, pnpm install now runs the projects' own lifecycle scripts, such as prepare, even when node_modules is already up to date #16545.

    • pnpm self-update now fails for Homebrew-installed pnpm and prints the brew upgrade command for the installed formula, such as brew upgrade pnpm or brew upgrade pnpm@11. It used to install a second copy of pnpm that the Homebrew one kept shadowing #16547.

  4. 11.28.4

    3 October 2026
    Pnpm self-update now fails for Homebrew-installed pnpm and prints the brew upgrade command for the installed formula, such as brew upgrade pnpm or brew upgrade pnpm@11. It used to install a second copy of pnpm that the Homebrew one kept shadowing #16547.

    Section of a shared release note

    Updating pnpm

    • pnpm self-update now fails for Homebrew-installed pnpm and prints the brew upgrade command for the installed formula, such as brew upgrade pnpm or brew upgrade pnpm@11. It used to install a second copy of pnpm that the Homebrew one kept shadowing #16547.

    • On Windows, pnpm self-update now replaces a pnpm.exe left in PNPM_HOME or in PNPM_HOME\bin. In PNPM_HOME, that executable kept running the old version after a successful update. In PNPM_HOME\bin, the update failed with EPERM. If the executable was in PNPM_HOME, self-update now asks you to run pnpm setup #9094.

    • pnpm can now switch to a packageManager version below 11 on x64 musl Linux, such as Alpine #16467.

    • A devEngines.packageManager range now records the running pnpm in pnpm-lock.yaml only if it meets minimumReleaseAge. Otherwise pnpm records the newest version in the range that meets it. If no version in the range does, pnpm still records the running pnpm #16431.

  5. 12.9.0

    2 October 2026
    Pnpm no longer downloads the project's pinned pnpm version again on every command when nodeVersion in pnpm-workspace.yaml names a different Node.js major than the node on PATH. Before, each of those commands took about a second longer and failed without network access #16497.

    Section of a shared release note

    The pinned pnpm and pnpm self-update

    • pnpm no longer downloads the project's pinned pnpm version again on every command when nodeVersion in pnpm-workspace.yaml names a different Node.js major than the node on PATH. Before, each of those commands took about a second longer and failed without network access #16497.

    • Several pnpm commands started at once in a project that pins packageManager no longer fail with The process cannot access the file because it is being used by another process on Windows while the pinned pnpm is being installed.

    • pnpm can now switch to a packageManager version below 11 on x64 musl Linux, such as Alpine #16467.

    • A devEngines.packageManager range no longer makes pnpm replace the version recorded in pnpm-lock.yaml with the running pnpm while the recorded version still satisfies the range. When pnpm does record a version, it records the running pnpm only if it meets minimumReleaseAge. Otherwise it records the newest version in the range that meets it, or the running pnpm if none does #16431.

    • On Windows, pnpm self-update now replaces a pnpm.exe left in PNPM_HOME or in PNPM_HOME\bin. Windows ran that executable in place of the updated pnpm.cmd shim, so pnpm --version kept printing the old version after a successful update. If the executable was in PNPM_HOME, self-update now asks you to run pnpm setup #9094.

    • pnpm self-update now checks that a version installed as the JavaScript pnpm can start before making it the global pnpm. If Node.js is missing, the update fails and the current pnpm stays in place.

  6. 11.28.3

    30 September 2026
    Pnpm 11.28.3 updates undici to clear a security advisory, fixes "database disk image is malformed" errors when several pnpm processes share a store, and makes packages, catalogs, projects, and commands named like constructor work.

    pnpm 11.28.3 updates undici to clear a security advisory, fixes "database disk image is malformed" errors when several pnpm processes share a store, and makes packages, catalogs, projects, and commands named like constructor work.

    Patch Changes

    Installing packages

    • security

      pnpm now ships undici 7.29.1, so security scans of pnpm no longer report GHSA-3wwx-pv8p-q78v.

    • pnpm no longer fails with "database disk image is malformed" or reads stale store entries while another pnpm process writes to the same store.

    • Names that match built-in JavaScript object properties, such as constructor, toString, or __proto__, now work like any other name. pnpm crashed, wrote a wrong lockfile, or silently skipped such names in:

      • pnpm add, pnpm install, and pnpm import, for dependencies, peer dependencies, and file: dependencies that point to a directory named constructor.

      • Catalog entries and catalog names. Pruning unused entries crashed, and a new catalog named toString was not written.

      • Workspace projects, project directories, and files inside injected packages.

      • Registry prefixes and override version references such as $toString.

      • Hoisting, pnpm list, and pnpm why.

      • Command names. pnpm constructor runs the constructor script like any other unknown command, and pnpm help constructor no longer crashes.

      • Resolving through a pnpr server when a project lives in a directory named constructor.

    • pnpm install no longer re-resolves an up-to-date lockfile on every run when a patched package is a peer in a peer cycle #16418.

    • POSIX bin shims and the pnpm, pn, pnpx, and pnx launchers now run inside a Nix build, where the system default path holds none of the utilities they call. Installing again replaces the shims already in node_modules #16377.

    • In a project that pins another pnpm version, pnpm now passes a command with an option it does not know to the pinned version. Before, pnpm install --auto-dedupe failed with "Unknown option" even though the pinned pnpm supports it #16353.

    • pnpm now fails with ERR_PNPM_INVALID_ALLOW_BUILDS when allowBuilds is not an object or one of its values is not true, false, or a string. Such values used to be ignored silently.

    • Removing a dependency whose bins are declared through directories.bin no longer leaves broken shims in node_modules/.bin.

    • A custom resolver's shouldRefreshResolution hook that rejects no longer crashes pnpm with an unhandled rejection when another hook has already asked for a refresh.

    Updating dependencies

    • When minimumReleaseAge hides the version that latest points to, pnpm now falls back to a prerelease of the same major before a stable version of an older major. A stable version of the same major is still preferred. For example, while a new 1.0.0 is too new, pnpm picks 1.0.0-beta.4 rather than an old 0.0.1 #16388.

    • pnpm --filter <project> update <pkg> now fails with ERR_PNPM_NO_PACKAGE_IN_DEPENDENCIES when the selected projects do not depend on <pkg>, also in a workspace with a shared lockfile and a root project. It used to exit successfully.

    • security

      pnpm audit --fix now updates vulnerable packages in a single project that sets updateConfig.ignoreDependencies. It used to leave them on the vulnerable version.

    • pnpm update --global now removes hard-linked executables from PNPM_HOME when migrating packages from the old global layout #16420.

    • Updating a pinned GitHub Action now rewrites the version in its # vX.Y.Z comment even when the action name contains the same version text. The action name used to change while the comment kept the old version.

    Workspaces and deploy

    • pnpm deploy no longer fails with ERR_PNPM_DEPLOY_AMBIGUOUS_PEER in a workspace with injectWorkspacePackages: true when a workspace package also lists its peer dependency as a dev dependency #16375.

    • pnpm deploy no longer copies the workspace root's packageManager and devEngines.packageManager fields into the deployed package.json #16403.

    • --filter fixes:

      • A ...pkg... selector combined with another dependents selector, such as --filter ...a --filter ...b..., no longer adds the dependencies of the other selector's dependents.

      • --filter "[<since>]" now detects changes in projects whose directory names contain non-ASCII characters. The change used to be credited to the parent project.

  7. 12.8.2

    30 September 2026
    Pnpm 12.8.2 fixes a startup crash on Linux ppc64le and UnknownIssuer errors on systems without CA certificates. pnpm run no longer installs before every script on CI when autoDedupe is enabled, and resolution and hoisted installs on macOS are faster.

    pnpm 12.8.2 fixes a startup crash on Linux ppc64le and UnknownIssuer errors on systems without CA certificates. pnpm run no longer installs before every script on CI when autoDedupe is enabled, and resolution and hoisted installs on macOS are faster.

    Patch Changes

    Platforms and environments

    • Fixed pnpm crashing on startup on Linux ppc64le #16380.

    • Fixed installs failing with UnknownIssuer on Linux systems without CA certificates, such as node:24-slim, when NODE_EXTRA_CA_CERTS is set. The extra certificates now extend the bundled CA roots #16365.

    • pnpm now creates its store operation locks and other per-user lock files in $XDG_RUNTIME_DIR when it points to a directory only the user can write to. Otherwise, pnpm still uses /tmp on Linux and macOS. Sandboxes that block writes to /tmp can point XDG_RUNTIME_DIR at a writable directory #16390.

    • POSIX bin shims and the pnpm, pn, pnpx, and pnx launchers now run inside a Nix build, where the system default path holds none of the utilities they call. Installing again replaces the shims already in node_modules #16377.

    • In a project that pins another pnpm version, pnpm now passes a command with an option it does not know to the pinned version. Before, pnpm rejected the option before switching, so pnpm install --auto-dedupe failed with "Unknown option" even though the pinned pnpm supports it #16353.

    Installing and resolving dependencies

    • pnpm install --frozen-lockfile now fails when Cargo.lock does not satisfy a dependency requirement in Cargo.toml. The error names the crate and the version the lockfile holds #16355.

    • pnpm install returns "Already up to date" again in a workspace with injected workspace dependencies and a shared lockfile. Since 12.7.0 every repeat install in such a workspace ran the full install and copied the injected projects again.

    • With injectWorkspacePackages: true, a fresh pnpm install now records a workspace dependency as link: when its injected copy differs from the project only by an optional peer that peer-dependent dedupe merges. It was recorded as a peer-suffixed file: copy #16354.

    • pnpm dedupe --check now passes right after pnpm dedupe when deduplication merges variants of a package that differ only in their peers. A lockfile key whose peer suffix named a merged variant now names the variant that replaced it #16356.

    • When minimumReleaseAge hides the version that latest points to, pnpm now falls back to a prerelease of the same major before a stable version of an older major. A stable version of the same major is still preferred. Before, while a new 1.0.0 was too new, latest fell back to an old 0.0.1 even though 1.0.0-beta.4 had been latest until then #16388.

    • Git-hosted dependencies now respect pmOnFail. If it is set to anything other than download, a git-hosted dependency that pins a pnpm version is prepared by the running pnpm, and pnpm does not download the pinned version #16376.

    • pnpmfile hooks such as readPackage now run once for a dependency that several packages request at the same time. They could run twice for it before.

    • childConcurrency now defaults to 5, the documented value. It used to be capped at 4 and to follow the host's CPU count.

    Running scripts

    • pnpm run and pnpm exec no longer install dependencies before every script on CI when autoDedupe is enabled. pnpm install --frozen-lockfile now keeps the deduplication record left by an earlier install #16374.

    • On macOS and Linux, lifecycle scripts and pnpm run now always get PATH from the PATH variable. When the environment also held a Path variable, a script sometimes got Path's value, and failed with node: not found #16308.

    • pnpm run now exits after a SIGTERM in a container where pnpm is PID 1 and the script runs pnpm again, as "start": "pnpm serve" does. Since 12.6.0 it kept waiting after the script had shut down, until the container runtime killed it.

    Other commands and settings

    • pnpm config get globalShims, pnpm shim list, and global installs no longer read globalShims from a project's pnpm-workspace.yaml. Only the global config file, the pnpm home's own pnpm-workspace.yaml, and PNPM_CONFIG_GLOBAL_SHIMS set it, so a repository cannot choose which globally installed packages get project-aware shims.

    • pnpm config set --location=project refuses a machine-level setting such as stateDir or scope with ERR_PNPM_CONFIG_SET_NOT_A_PROJECT_SETTING, which names where the setting belongs. pnpm config delete still clears such a key from a project's pnpm-workspace.yaml.

    • pnpm deploy no longer fails with ERR_PNPM_DEPLOY_AMBIGUOUS_PEER in a workspace with injectWorkspacePackages: true when a workspace package lists its peer dependency as a dev dependency too #16375.

    • pnpm deploy no longer copies the workspace root's packageManager and devEngines.packageManager fields into the deployed package.json #16403.

    • pnpm publish now includes bare README files and README files with Markdown extensions such as readme.markdown in registry metadata #12704.

    • pnpm store prune now removes the packages that only expired pnpm dlx cache entries used. They were left in the store until the next pnpm store prune #16383.

    Performance

    • Sped up dependency resolution in large workspaces, and when many dependencies request different ranges of the same package. Resolution also uses less memory.

  8. 10.34.6

    28 September 2026
    : pnpm self-update now resolves and verifies pnpm through registry, authentication, proxy, and TLS settings from trusted non-project configuration. Project configuration and the default project pnpmfile can no longer redirect the pnpm download or disable engine identity verification.

    Patch Changes

    • e7888e5: pnpm self-update now resolves and verifies pnpm through registry, authentication, proxy, and TLS settings from trusted non-project configuration. Project configuration and the default project pnpmfile can no longer redirect the pnpm download or disable engine identity verification.

    • 46bc7c9: pnpm no longer tells you to update itself with Corepack or with pnpm add -g:

      • The update notification now suggests pnpm self-update, or the standalone install script when pnpm is running under Corepack. It used to suggest corepack use pnpm@<version>, or pnpm add -g pnpm / pnpm add -g @pnpm/exe when pnpm was not installed by the standalone script — but pnpm add -g refuses to install pnpm and points at pnpm self-update anyway, and @pnpm/exe is not published for pnpm v12 or newer, where the unscoped pnpm package is itself the native executable.

      • pnpm self-update under Corepack now points at the standalone install script too, instead of telling you to update pnpm with Corepack.

    • security

      46bc7c9: Updated adm-zip to v0.6.0, which fixes a memory-exhaustion vulnerability where a crafted ZIP file could make it allocate 4 GB of memory. adm-zip is used to extract the Node.js, Bun, and Deno archives that pnpm downloads on Windows.

    • Updated the embedded Node.js release keys to the current canonical nodejs/release-keys list.

    • Updated the embedded npm registry signing keys to the set currently advertised by npm.

    • 702ad5f: Update the embedded Node.js release keys with the new key added to nodejs/release-keys (Stewart X Addison, 655F3B5C1FB3FA8D1A0CA6BDE4A7D232B936D2FD).

  9. 12.8.1

    28 September 2026
    Pnpm 12.8.1 fixes pnpm install --frozen-lockfile rejecting lockfiles with injected workspace packages that have peers, restores the executable bit on files of local directory dependencies, makes pnpm dedupe converge, and uses less CPU on many-core machines.

    pnpm 12.8.1 fixes pnpm install --frozen-lockfile rejecting lockfiles with injected workspace packages that have peers, restores the executable bit on files of local directory dependencies, makes pnpm dedupe converge, and uses less CPU on many-core machines.

    Patch Changes

    • pnpm install --frozen-lockfile no longer rejects a freshly generated lockfile when an injected workspace package has peer dependencies #16332.

    • Executable files in a file: directory dependency or an injected workspace package keep their executable bit again. Since 12.8.0, pnpm installed these files without the permissions they have in their project.

    • pnpm dedupe now reaches a stable lockfile when a package's peer suffix is long enough to be hashed. Before, each run could switch that package's key between the hashed and the spelled-out suffix, so pnpm dedupe --check always failed #16331.

    • pnpm install --frozen-lockfile, the default in CI, now uses less CPU on machines with more than 8 cores. Warm installs on many-core Windows machines got up to 10% faster. Frozen installs now link with at most 16 worker threads.

    • verifyDepsBeforeRun no longer reports dependencies as outdated after a filtered install just because pnpm-lock.yaml has a newer modification time. It checks the lockfile against the packages that install put in place. Before, pnpm run reinstalled the whole workspace with lifecycle scripts on, for example after a Docker COPY brought in a lockfile with a newer mtime #16322.

      After a filtered install, verifyDepsBeforeRun now also checks that the install put the selected projects' dependencies in place. A node_modules directory alone no longer counts as proof.

    • pnpm run and pnpm exec no longer install a project that has never been installed and has nothing to install. Such a project declares no dependencies, no peer dependencies that autoInstallPeers would fetch, and no install lifecycle scripts. The command now runs without writing node_modules or pnpm-lock.yaml #16313.

    • pnpm update -g --latest now upgrades globally installed packages beyond their saved version ranges #16320.

  10. 11.28.2

    28 September 2026
    Pnpm 11.28.2 fixes pnpm install skipping every workspace project whose common ancestor is the filesystem root, and stops pnpm run from reinstalling or installing when nothing needs it.

    pnpm 11.28.2 fixes pnpm install skipping every workspace project whose common ancestor is the filesystem root, and stops pnpm run from reinstalling or installing when nothing needs it.

    Patch Changes

    • pnpm install reported success without installing anything when the workspace projects' common ancestor was the filesystem root, such as / or a drive root like C:\. It now installs these projects #16328.

    • verifyDepsBeforeRun no longer reports dependencies as outdated after a filtered install just because pnpm-lock.yaml has a newer modification time. It checks the lockfile against the packages that install put in place. Before, pnpm run reinstalled the whole workspace with lifecycle scripts on, for example after a Docker COPY brought in a lockfile with a newer mtime #16322.

      After a filtered install, verifyDepsBeforeRun now also checks that the install put the selected projects' dependencies in place. A node_modules directory alone no longer counts as proof.

    • pnpm run and pnpm exec no longer install a project that has never been installed and has nothing to install. Such a project declares no dependencies, no peer dependencies that autoInstallPeers would fetch, and no install lifecycle scripts. The command now runs without writing node_modules or pnpm-lock.yaml #16313.

  11. 12.8.0

    28 September 2026
    Pnpm update --global now reinstalls the global packages that pnpm 10 installed into the previous global directory, /5, so their commands are linked into the pnpm home bin directory again and pnpm list --global lists them. Once every package is migrated, pnpm deletes the previous directory and the commands pnpm 10 linked into the pnpm home #11528.

    Section of a shared release note

    Global packages, pnpm versions, and runtimes

    • pnpm update --global now reinstalls the global packages that pnpm 10 installed into the previous global directory, <global-dir>/5, so their commands are linked into the pnpm home bin directory again and pnpm list --global lists them. Once every package is migrated, pnpm deletes the previous directory and the commands pnpm 10 linked into the pnpm home #11528.

    • A signal sent to pnpm, such as SIGTERM, now reaches the pnpm that pnpm switches to because of packageManager or devEngines.packageManager, and the one that pnpm with runs. The signal used to be dropped, so scripts running under that pnpm never got to shut down #9948.

    • On arm64 musl Linux, such as Alpine on ARM, switching to a pinned pnpm older than 12 now runs the JavaScript pnpm package. The standalone executable of those versions crashed at startup on that platform #10443.

    • Global shims such as node now work when pnpm runs through a relative symlink, as with a Homebrew install. They were copies of that symlink and did not resolve from the global bin directory #15691.

    • pnpm env remove --global deletes Node.js versions that pnpm installed into its own store, including when another tool installed pnpm #8357.

    • pnpm self-update no longer suggests a downgrade when minimumReleaseAge holds back the registry's latest release. It now says that release is still within the cutoff #12006.

  12. 11.28.1

    28 September 2026
    Pnpm update --global now reinstalls the global packages that pnpm 10 installed into the previous global directory, /5, so their commands are linked into the pnpm home bin directory again and pnpm list --global lists them. Once every package is migrated, pnpm deletes the previous directory and the commands pnpm 10 linked into the pnpm home #11528.

    Section of a shared release note

    Global packages, pnpm versions, and runtimes

    • pnpm update --global now reinstalls the global packages that pnpm 10 installed into the previous global directory, <global-dir>/5, so their commands are linked into the pnpm home bin directory again and pnpm list --global lists them. Once every package is migrated, pnpm deletes the previous directory and the commands pnpm 10 linked into the pnpm home #11528.

    • pnpm env remove --global deletes Node.js versions that pnpm installed into its own store, including when another tool installed pnpm #8357.

    • pnpm self-update no longer suggests a downgrade when minimumReleaseAge holds back the registry's latest release. It now says that release is still within the cutoff #12006.

    • @pnpm/exe no longer ships a binary for arm64 musl Linux, such as Alpine on ARM. The published binary crashed with a segmentation fault at startup. Installing @pnpm/exe on that platform now fails with an error that suggests npm install -g pnpm or pnpm 12 #10443.

    • The macOS and Linux release archives no longer include Windows-only files, such as node-gyp.cmd and the fastlist executables #11352.

  13. 12.7.0

    25 September 2026
    Global commands such as pnpm add --global, pnpm list --global, and pnpm bin --global now run with the pnpm you invoked, even in a project that pins another pnpm version. Previously, a pin with onFail: "download" switched them to the pinned pnpm, and a pinned pnpm 10 or older failed because its global bin directory was not in PATH #14531.

    Section of a shared release note

    Global packages, pnpm versions, and runtimes

    • Global commands such as pnpm add --global, pnpm list --global, and pnpm bin --global now run with the pnpm you invoked, even in a project that pins another pnpm version. Previously, a pin with onFail: "download" switched them to the pinned pnpm, and a pinned pnpm 10 or older failed because its global bin directory was not in PATH #14531.

    • pnpm add -g, pnpm update -g, and pnpm remove -g no longer fail with ERR_PNPM_PACKAGE_MANIFEST_IO_ERROR when another global package's link into the store dangles, for example after the store was pruned. The pnpm install script failed the same way on such a machine.

    • pnpm update --global now skips a global package installed from a file: path that no longer exists, prints a warning, and updates the remaining global packages. Previously the whole update failed with ERR_PNPM_LINKED_PKG_DIR_NOT_FOUND #12533.

    • pnpm self-update run in a project that pins pnpm through packageManager or devEngines.packageManager now also updates the global pnpm, as it does outside a project #14747.

    • pnpm self-update no longer leaves the previous pnpm in the global packages when it was installed as @pnpm/exe. pnpm ls -g now lists a single pnpm #14709. pnpm setup now installs pnpm under the package name pnpm too, so both commands leave the same shims in the global bin directory. After a self-update on Windows, PowerShell ran pnpm through pnpm.cmd and asked "Terminate batch job (Y/N)?" on Ctrl+C #15567.

    • pnpm setup failed with Text file busy (os error 26) when $PNPM_HOME/bin already held pn, pnpx, or pnx as links to the running pnpm executable. It now replaces those files and completes #15494.

    • pnpm setup no longer deletes aliases and other lines that sit between a # pnpm comment and the pnpm block in a shell startup file #7067.

    • When pnpm switches to the version a project pins, the minimumReleaseAge approvals for that version are now added to minimumReleaseAgeExclude in the project's pnpm-workspace.yaml. A project without that file gets one. Global commands leave the project's settings unchanged #15396.

    • pnpm env remove now cleans up dangling Node.js executables and shims. Surviving global commands remain intact.

    • Node.js runtime resolution now supports Windows ARM64. Node.js 20 and newer resolve native win-arm64 builds, and older versions fall back to win-x64 under emulation #7123.

  14. 11.28.0

    25 September 2026
    Global commands such as pnpm add --global, pnpm list --global, and pnpm bin --global now run with the pnpm you invoked, even in a project that pins another pnpm version. Previously, a pin with onFail: "download" switched them to the pinned pnpm, and a pinned pnpm 10 or older failed because its global bin directory was not in PATH #14531.

    Section of a shared release note

    Global packages, pnpm versions, and runtimes

    • Global commands such as pnpm add --global, pnpm list --global, and pnpm bin --global now run with the pnpm you invoked, even in a project that pins another pnpm version. Previously, a pin with onFail: "download" switched them to the pinned pnpm, and a pinned pnpm 10 or older failed because its global bin directory was not in PATH #14531.

    • pnpm add -g, pnpm update -g, and pnpm remove -g now recover a global package group whose entire node_modules directory was deleted. pnpm remove -g leaves such a group's command shims in the global bin directory #15093. These commands no longer fail with ERR_PNPM_PACKAGE_MANIFEST_IO_ERROR when another global package's link into the store dangles, for example after the store was pruned. The pnpm install script failed the same way on such a machine.

    • pnpm update --global now skips a global package installed from a file: path that no longer exists, prints a warning, and updates the remaining global packages. Previously the whole update failed with ERR_PNPM_LINKED_PKG_DIR_NOT_FOUND #12533.

    • pnpm update -g no longer asks more than once for approval of the same immature name@version when minimumReleaseAgeStrict is enabled #15091.

    • pnpm self-update run in a project that pins pnpm through packageManager or devEngines.packageManager now also updates the global pnpm, as it does outside a project #14747.

    • pnpm self-update no longer leaves the previous pnpm in the global packages when it was installed as @pnpm/exe. pnpm ls -g now lists a single pnpm #14709.

    • pnpm setup no longer deletes aliases and other lines that sit between a # pnpm comment and the pnpm block in a shell startup file #7067.

    • pnpm env remove now cleans up dangling Node.js executables and symlinks. Surviving global commands remain intact.

    • Node.js runtime resolution now supports Windows ARM64. Node.js 20 and newer resolve native win-arm64 builds, and older versions fall back to win-x64 under emulation #7123.

  15. 12.6.0

    22 September 2026
    Pnpm 12.6.0 ships with automatic dependency deduplication, relocatable node_modules, package.yaml manifest editing, and --save-types support.

    pnpm 12.6.0 ships with automatic dependency deduplication, relocatable node_modules, package.yaml manifest editing, and --save-types support.

    Minor Changes

    • autoDedupe deduplicates compatible dependency versions during installation #7258. Enable it in pnpm-workspace.yaml or use pnpm install --auto-dedupe or pnpm add --auto-dedupe. Frozen installs leave the lockfile unchanged.

    • pnpm install, pnpm run, and pnpm exec on macOS and Linux now reuse a node_modules directory and bin shims that moved or were copied together with their project #6937. The first command after the move checks the tree and records its new location, so project commands in node_modules/.bin keep working.

    • pnpm add --save-types saves available @types/* packages in devDependencies alongside registry dependencies #3868. Packages that declare bundled TypeScript types are skipped. Set saveTypes: true in pnpm-workspace.yaml to enable this by default.

    • package.yaml manifests can now be updated by pnpm add, pnpm update, pnpm remove, pnpm pkg, pnpm link, pnpm set-script, and pnpm version #2008. Existing comments and key order are preserved.

    • Catalog entries can now use the file: and link: protocols #8642. A relative path or bare path in an entry, such as ./tarballs/foo.tgz, is measured from the directory holding pnpm-workspace.yaml.

    • pnpm tasks status lists running and waiting tasks in each concurrency group, and waiting tasks now take available slots in arrival order with higher priority tasks going first #15208. If workspaces use different limits for the same group, a later task can take a free slot that earlier tasks cannot use. A package script named tasks takes precedence; use pnpm pm tasks status when that script exists.

    • pnpm cache prune deletes registry metadata cache directories that this version of pnpm can no longer read #15046. pnpm cache prune --dry-run lists what it would delete without removing anything.

    • macosBackup.excludeModulesDir and macosBackup.excludeStoreDir on macOS can now exclude newly created modules, virtual-store, and package-store directories from Time Machine #6440. Set either to true in global configuration or using the PNPM_CONFIG_MACOS_BACKUP_EXCLUDE_MODULES_DIR and PNPM_CONFIG_MACOS_BACKUP_EXCLUDE_STORE_DIR environment variables.

    • pnpm add --tilde is now an alias for --save-prefix=~ #12863. The Yarn -T shorthand is not supported.

    • progress setting and --no-progress option now turn off dependency and download progress lines #14065. Warnings, lifecycle output, and the dependency summary are still printed.

    Patch Changes

    Security

    • security

      POSIX bin shims now take cygpath and wslpath from the system default path on Cygwin, MSYS2, and WSL2 so a dependency cannot redirect another package's shim #14866.

    • security

      pnpm install warnings no longer carry the text of a package's deprecation notice, naming only the deprecated package and version #15099. A deprecation warning names the newest non-deprecated version when one exists, and control characters and line separators are stripped from package identifiers and warnings.

    • security

      pnpm install and other commands that report configuration warnings now warn when environment variables in project .npmrc credentials are ignored #15051.

    Installing packages

    • pnpm install --frozen-lockfile now succeeds when an optional dependency was unresolvable and skipped by the install that wrote the lockfile #3960.

    • pnpm install --frozen-lockfile no longer installs dependencies of projects removed from pnpm-workspace.yaml #15248. Missing local tarballs used only by those projects no longer fail the install.

    • pnpm ci now empties node_modules before installing in a project that declares a clean script #15276.

    • pnpm install --force now re-imports every package into the virtual store #15030 and removes obsolete dependency links inside virtual-store packages when their dependencies change #15039.

    • preinstall script for the root project now runs before dependencies are resolved and linked #3760.

    • pnpm install now runs pnpm:devPreinstall when the root project uses package.yaml #15168.

    • pnpm install now enforces the root project's engines.node range when engineStrict is enabled #3016.

    • pnpm install now uses the running Node.js when devEngines.runtime declares a range without onFail: download #15230.

    • pnpm install no longer hangs when a git dependency is fetched over SSH and ssh prompts for a passphrase or host key confirmation, running ssh in batch mode instead #2227.

    • pnpm install now installs git-hosted dependencies without preparing them when their builds are explicitly denied by allowBuilds #10522.

    • pnpm install now reuses an in-flight tarball download when another resolution of the same archive still needs its package.json #15037.

    • pnpm install --prod no longer downloads registry packages that only a devDependency reaches #881.

  16. 11.27.1

    20 September 2026
    Pn, pnpx, and pnx now run the pnpm installed alongside them. They used to look pnpm up on PATH. That failed when the directory holding them was not on PATH, and it silently handed the call to an unrelated pnpm when one came first there #14803.

    Patch Changes

    • pn, pnpx, and pnx now run the pnpm installed alongside them. They used to look pnpm up on PATH. That failed when the directory holding them was not on PATH, and it silently handed the call to an unrelated pnpm when one came first there #14803.

    • The @zkochan/cmd-shim package is now available as @pnpm/bins.cmd-shim.

    • pnpm cache list-registries now prints the registry URL, matching pnpm cache view. It printed https%3A+registry.npmjs.org before and prints https://registry.npmjs.org/ now #15046.

    • pnpm deploy no longer installs the dependencies of the workspace root project into the deploy directory #6437.

    • Install warnings no longer carry the text of a package's deprecation notice. The warning names the deprecated package and version, and the pnpm:deprecation event no longer carries the notice either. pnpm view still shows it on request.

      A deprecation warning now names the newest version of the package that is not deprecated, and says when reaching it means widening the range you declared:

      WARN  deprecated foo@1.0.0. 2.3.1 is not deprecated, outside the range you declared.

      pnpm works this out from the metadata it already fetched, so it costs no extra request. An install that reuses the lockfile without fetching metadata names no version.

      pnpm strips control characters from the package name and version in a deprecation warning, and from the notice pnpm outdated --long prints.

      The text sanitizer now also strips the Unicode line and paragraph separators U+2028 and U+2029.

    • pnpm exec <command> and pnpm <command> run from a subdirectory of a project now find the executables installed in the project's node_modules/.bin. The command still runs in the subdirectory. PNPM_PACKAGE_NAME names the project #5068.

    • pnpm exec and pnpm dlx now wait for the command to finish shutting down after Ctrl+C. A signal sent to pnpm alone now reaches the command, the way it does with pnpm run. pnpm used to exit on the interrupt and terminate the command while it was still shutting down #7374.

    • Warnings about ignored environment variables in project .npmrc credentials now link to the npmrc documentation pnpm/pnpm#15051.

    • pnpm audit --interactive --fix=update no longer opens a second prompt for selecting dependencies to update #14927.

    • Fixed pnpm dedupe requiring a second pass after bumping a direct dependency in package.json pnpm/pnpm#14987.

    • pnpm deploy now writes plain versions for registry dependencies with peer dependencies in the deployed package.json. The deployed lockfile retains the resolved peer bindings. npm aliases keep their target package names #14873.

    • pnpm publish now allows a detached Git HEAD in CI, including checkouts of release tags. The working tree must still be clean. Branch and remote-history checks still apply when HEAD is attached pnpm/pnpm#5894.

    • pnpm dlx and pnx now prompt to approve dependency build scripts in interactive terminals. Cached packages with pending builds also prompt for approval. Without an interactive terminal, use --allow-build to allow the required builds. Fixes pnpm/pnpm#14943.

    • pnpm install --force now removes obsolete dependency links inside virtual-store packages when their dependencies change. Invalid dependency names are ignored during obsolete-link cleanup #15039.

    • pnpm add -g and pnpm update -g now 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.

    • Resolving a Node.js runtime now fails when unofficial-builds.nodejs.org cannot be reached. pnpm used to ignore that failure and leave the musl builds out of pnpm-lock.yaml. pnpm update then wrote a different lockfile on a machine whose network blocks the mirror pnpm/pnpm#14813.

    • pnpm now deduplicates a package whose child dependency resolved an optional peer in one workspace project but not in another. Two copies of next could appear when only some projects could reach styled-jsx's optional babel-plugin-macros peer #14800.

    • Fixed shell completion of package scripts for pnpm run and pnpm run-script pnpm/pnpm#15034.

      Bash completion now preserves literal script names containing glob characters and shell punctuation in pnpm v11 and v12.

    • pnpm sbom now publishes a valid URL in the CycloneDX externalReferences.url and the SPDX homepage. An npm shorthand such as vercel/ms or gitlab:group/subgroup/project is expanded to the git+https URL npm derives for it. An scp-style remote such as git@github.com:vercel/ms.git is expanded the same way. Any other URL is published in its normalized form, without embedded credentials. A value that names no repository, an email address for example, is left out. pnpm used to publish the raw value, so a shorthand produced a URL that consumers such as Dependency-Track reject pnpm/pnpm#14773.

    • pnpm setup now describes the displayed configuration changes as "the following configuration changes."

    • pnpm --version now reports why the pnpm version a project pins cannot be installed or recorded, then prints the version of the running CLI. It used to fail, which made the command unusable where the filesystem is read-only. pnpm --version also honors --store-dir and its --store alias now #14831.

    • pnpm install --force now reinstalls dependencies when the manifest and lockfile are unchanged. It previously reported "Already up to date" without reinstalling. Files changed in node_modules are restored when the store content is intact. Combining --force with --frozen-store now reports a configuration conflict on repeat installs #919.

    • pnpm install now installs git-hosted dependencies without preparing them when their builds are explicitly denied by allowBuilds. Dependencies that require preparation still need an explicit allow or deny decision pnpm/pnpm#10522.

    • pnpm runtime set and pnpm env use now use the pnpm version that started the command. They could run a different installed pnpm when the command was started through Corepack or another wrapper.

    • The install summary now names the version each dependency resolved to when node-linker is hoisted. It also lists what an install restores after node_modules is deleted, and both sides of a version change. The summary showed the range recorded in package.json, or nothing at all #15161.

    • The @pnpm/npm-lifecycle package is now available as @pnpm/exec.npm-lifecycle.

    • Fixed minimumReleaseAge making pnpm download a package's full metadata again on every install. The cached copy carried a validator the registry could not match, so pnpm could never revalidate it pnpm/pnpm#15103.

    • pnpm now measures a pnpm.overrides entry written as a bare path, such as ./local-dep, from the directory holding pnpm-workspace.yaml. It used to be measured from each package the override rewrote, so the dependency linked to a directory that does not exist #11131.

    • pnpm now preserves scalar YAML anchors and aliases when editing pnpm-workspace.yaml. Removing the entry that defines an anchor keeps surviving aliases valid. Entries updated to different values are written separately #8245.

  17. 12.5.1

    18 September 2026
    Pnpm now reports an unknown task setting in pnpm-workspace.yaml and carries on. It used to refuse to start, so a project could not use a task setting that only the pnpm version its packageManager pins reads. The setting is still an error when the running pnpm is that pinned version.

    Patch Changes

    • pnpm now reports an unknown task setting in pnpm-workspace.yaml and carries on. It used to refuse to start, so a project could not use a task setting that only the pnpm version its packageManager pins 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 registries entries now route packages by exact names or trailing-prefix patterns in packages. Registry declaration order no longer affects resolution. A matched package resolves exclusively from its assigned registry, including transitive and build dependencies. Use packages: ["*"] to declare the default index.

    • pnpm install no 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.toml linked from a dotfiles repository.

    • pnpm install now returns "Already up to date" in a workspace where dedupeDirectDeps left a project without a node_modules directory of its own. Such a project forced a full install on every run.

    • pnpm install no longer refuses the repeat-install fast path just because a changed pnpm-lock.yaml is 16 MiB or larger. Such a lockfile forced a full install on the run after every change.

  18. 12.5.0

    18 September 2026
    SupportedArchitectures now accepts a list of platforms, in place of the os, cpu and libc axes.supportedArchitectures:

    Section of a shared release note

    Configuring pnpm

    • supportedArchitectures now accepts a list of platforms, in place of the os, cpu and libc axes.

      supportedArchitectures:
        - linux-x64
        - darwin-arm64
        - win32-x64

      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 in linux-x64-musl or linux-x64-manylinux_2_28. The Rust target triple of the same machine is accepted too, so x86_64-unknown-linux-gnu names the platform linux-x64 names. A Linux platform that names no C library is the glibc platform. current is the platform the install runs on.

      The os, cpu and libc mapping keeps working and keeps its meaning.

    • Added concurrency groups for tasks. A task in pnpm-workspace.yaml can name a concurrencyGroup. The new concurrencyGroups setting 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 pipeline included. A task past the limit waits for a running one to finish. A script that calls pnpm run for a task of the same group runs under the slot its parent holds.

      tasks:
        test:rust:
          concurrencyGroup: cargo
      concurrencyGroups:
        cargo: 2
    • tools names the programs pnpm downloads, and mirror says where each one comes from.

      tools:
        node:
          mirror: https://mirror.example.com/node/download
          channels:
            nightly: https://nightly.example.com/
        bun:
          mirror: https://mirror.example.com/bun
        python:
          mirror: https://mirror.example.com/python-build-standalone/releases

      node, bun and python can be named. Any other tool is refused.

      mirror is the base a tool's own layout hangs off.

      channels sends one release channel elsewhere. A channel neither it nor node-mirror:<channel> names is left to mirror. Only node publishes channels, so naming them for another tool is refused.

      Set it in the global config.yaml or in PNPM_CONFIG_TOOLS. A pnpm-workspace.yaml that names a tool mirror is ignored.

      pnpm pack-app downloads the Node.js it embeds through tools.node. node-mirror:<channel> keeps working and names the same thing as an entry under channels.

  19. 12.4.2

    15 September 2026
    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.

    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

    • 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 PATH for Windows path conversion, so dependency executables can still redirect them there.

    • security

      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/store by default #14859.

    • pnpm install on Windows no longer fails with ERR_PNPM_PACKAGE_MANAGER_REMOVE_MODULES_DIR when clearing node_modules containing linked dependencies, such as when changing nodeLinker #14790.

    • pnpm install <pkg> now accepts --prod and --dev, including --prod=false #14868.

    • pnpm install and pnpm update now honor --ignore-workspace in nested projects excluded from the surrounding workspace. The flag also skips that workspace's settings during the packageManager check #14809.

    • pnpm install on macOS no longer reuses stale files for file: tarball or git-hosted tarball dependencies.

    • pnpm install in a single-project directory now detects package.json edits made while the previous install was finishing #14890.

    • pnpm install --frozen-lockfile now removes packages no longer reachable from any project in pnpm-lock.yaml. This also prevents repeated lifecycle script execution and unnecessary installs before pnpm run and pnpm exec with verifyDepsBeforeRun #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 install now rejects invalid peerDependencies specifiers with ERR_PNPM_INVALID_PEER_DEPENDENCY_SPECIFICATION. A value such as "foo": "foo@1.0.0" previously created a broken directory link #14791.

    • pnpm deploy now writes plain registry versions in the deployed package.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 a package.json as @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 next with styled-jsx's optional babel-plugin-macros peer #14800.

    • pnpm update now settles the lockfile in one run when an upgrade removes the package providing an optional peer dependency #14895.

    • pnpm update --no-save now preserves override-applied specifiers for dependencies it is not updating, preventing subsequent frozen installs from failing with ERR_PNPM_OUTDATED_LOCKFILE #14836.

    • pnpm update --no-save now succeeds under minimumReleaseAgeStrict when every resolved version is old enough #14835.

    Performance

    • Workspace installs and pnpm peers check are 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-lockfile now reuses pylock.toml across compatible Python targets, including after kernel updates. Reuse requires unchanged requirements, index, and requires-python, compatible wheels, and a locked dependency graph matching the target's markers #14843.

      The lockfile's environments marker 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-Python values, such as the trailing comma in openpyxl 3.0.x. pnpm treats these releases as declaring no interpreter range #14910.

    • pnpm add pypi:... now rejects unsupported --save-prefix values before editing the manifest or resolving dependencies.

    Workspaces and scripts

  20. 11.27.0

    12 September 2026
    NodeDownloadMirrors can now be set in the global config file (config.yaml) and through the PNPM_CONFIG_NODE_DOWNLOAD_MIRRORS environment variable, so a Node.js download mirror can be configured once for a machine instead of in every workspace #12124, #13611.PNPM_CONFIG_NODE_DOWNLOAD_MIRRORS='{"release":"https://npmmirror.com/mirrors/node/"}'

    Minor Changes

    • nodeDownloadMirrors can now be set in the global config file (config.yaml) and through the PNPM_CONFIG_NODE_DOWNLOAD_MIRRORS environment variable, so a Node.js download mirror can be configured once for a machine instead of in every workspace #12124, #13611.

      PNPM_CONFIG_NODE_DOWNLOAD_MIRRORS='{"release":"https://npmmirror.com/mirrors/node/"}'
    • Added a new setting trustPolicyExcludePrune (default: false). When enabled, pnpm add, pnpm update, and pnpm remove prune the entries of trustPolicyExclude in pnpm-workspace.yaml that the freshly written lockfile no longer resolves: versions that are gone are dropped (an entry is removed once none of its versions remain), and entries for packages that are no longer in the lockfile are removed too. Name patterns (@scope/*) are always kept. The cleanup is skipped when the install's lockfile does not cover the whole workspace (sharedWorkspaceLockfile: false), since entries another project still needs would look stale.

    Patch Changes

    • pnpm now reads the packageManager, devEngines.packageManager and runtime pins from the workspace root's package.json when lockfileDir is set. A project that moved its lockfile lost the pins it declared there #14633.

    • Fixed pnpm add -g, pnpm update -g, and pnpm remove -g mutating global bins or install directories after only partially reading an installed package group. If any declared package manifest is missing, malformed, or unreadable, pnpm now fails before activation or removal and leaves the existing global installation intact pnpm/pnpm#13796.

    • fetch-timeout now limits how long a request may make no progress. The timer restarts on every chunk that arrives. A large download over a slow connection is no longer aborted while data is still coming in. A connection that stops delivering data still fails after fetch-timeout #14604.

    • pnpm peers check no longer reports a peer dependency declared as workspace:^, workspace:~, or a bare workspace: as unmet. pnpm reported these as unmet whatever version the linked workspace project supplied #14770.

    • A readPackage hook that edits its argument in place no longer changes what a later install in the same command resolves. A deprecated notice read from the lockfile no longer carries over to another install either #13988.

    • pnpm install now auto-installs missing transitive peers when workspace projects share a dependency at different depths. This also removes incomplete duplicate peer contexts from the lockfile. Fixes pnpm/pnpm#14840.

    • GitHub Actions updates now stop if an action reference changes while its versions are being resolved. Unrelated workflow edits are preserved.

      GitHub Actions homepage links no longer expose server credentials. GitHub server URLs now require HTTPS, with HTTP allowed only for loopback hosts.

    • pnpm licenses list now reports the runtime downloaded through devEngines.runtime with onFail: "download". The command previously failed with ERR_PNPM_UNSUPPORTED_PACKAGE_TYPE #14172.

    • pnpm no longer creates a project pnpm-lock.yaml when devEngines.packageManager.onFail is download and lockfile writing is turned off with lockfile: false or --no-lockfile. pnpm still switches to the pinned version #14728.

    • A registry or @scope:registry set in an .npmrc now wins over the registry a pnpm login credential stored in the global config.yaml points at. Previously, after logging in to one registry, installs in a project whose .npmrc named a private registry went to the logged-in registry instead. They now go to the registry the .npmrc names #14614.

    • A patch that gives a dependency a preinstall, install, or postinstall script, or a binding.gyp, now runs that build. pnpm asks for build approval first, so the package is listed under "Ignored build scripts" until it is allowed to build. pnpm 12 ran nothing, and pnpm 11 ran it without asking #14648.

    • Registries that share a host but differ by URL path — one JFrog Artifactory, Nexus, AWS CodeArtifact or GitLab Packages instance serving several repositories — now get a metadata cache directory each. Previously they shared one, so resolving a package from one of them could answer with another's versions, integrity hashes and tarball URLs and fail with ERR_PNPM_TARBALL_URL_MISMATCH #13558.

      The URL scheme is part of the cache directory name too, so an http registry can no longer hand its metadata — which can be rewritten in transit — to a resolution configured for https at the same host.

      The first install after upgrading refetches registry metadata once. The package store is untouched.

      pnpm cache view now labels each entry with the full registry URL. It printed registry.npmjs.org before and prints https://registry.npmjs.org/ now.

      pnpm cache list-registries and pnpm cache list print the new directory names. Scripts that parse either command need updating.

    • Updated the embedded Node.js release keys to the current canonical nodejs/release-keys list.

    • pnpm sbom now omits package author fields when the manifest author name is empty or contains only whitespace pnpm/pnpm#14685. In a filtered or split workspace run, only a project with no author field inherits the workspace root's author.

    • pnpm sbom --sbom-format spdx now writes creationInfo.created with whole seconds, such as 2026-09-08T10:38:21Z. The timestamp carried fractional seconds, which strict SPDX consumers rejected #14684.

    • Windows filesystem operations now retry permission errors for up to one second. Permanent permission errors previously delayed failure by a minute. Sharing and lock violations retain their one-minute retry budget pnpm/pnpm#14682.

    • pnpm now writes node_modules/.package-map.json only when nodeExperimentalPackageMap is enabled. Nothing reads the file without that setting. An install that stops writing the map removes the one a previous install left.

    • security

      pnpm now unpacks a downloaded runtime archive into a randomly named directory inside the store. It previously used a predictable path, where another user of a shared store could plant a symlink and redirect the write outside the store (GHSA-vwc7-r8mq-g2x9).

All 1030 releases

Major versions

  • 12.xsince 26 August 2026 · latest 12.14.0 · 30 releases
  • 11.xsince 28 April 2026 · latest 11.28.6 · 55 releases
  • 10.xsince 7 January 2025 · latest 10.34.7 · 79 releases
  • 9.xsince 16 April 2024 · latest 9.15.9 · 45 releases
  • 8.xsince 27 March 2023 · latest 8.15.9 · 58 releases
  • 7.xsince 30 April 2022 · latest 7.33.7 · 96 releases
  • 6.xsince 5 April 2021 · latest 6.35.1 · 125 releases
  • 5.xsince 27 May 2020 · latest 5.18.11 · 100 releases
  • 4.xsince 7 October 2019 · latest 4.14.4 · 51 releases
  • 3.xsince 10 March 2019 · latest 3.8.1 · 34 releases
  • 2.xsince 19 May 2018 · latest 2.25.7 · 87 releases
  • 1.xsince 28 June 2017 · latest 1.43.1 · 130 releases
  • 0.xsince 8 March 2013 · latest 0.75.0 · 140 releases

Quality and security signals

What npm and deps.dev say about the latest release. Signals, not a verdict.

Reading npm and deps.dev…

Registry facts last checked 20 October 2026. Releases and advisories last read 20 October 2026.

Know when your own dependencies move

Inlinr tracks your coding time automatically. Switch dependency tracking on for a project and it reads that repository's manifest to show what is behind and what has been deprecated — off by default, one project at a time.