Packages/pnpm

Releases of pnpm

1030 stable releases, newest first. Release notes are kept for the last 90 days; older ones link to where they were published.

  1. 12.14.0

    15 October 2026

    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. 12.13.0

    13 October 2026

    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.

  3. 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.

    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.

  4. 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.

    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.

  5. 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.

    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.

  6. 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.

    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.

  7. 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.

    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.

  8. 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.

    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.

  9. 12.10.0

    6 October 2026

    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.

  10. 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.

    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.

  11. 12.9.0

    2 October 2026

    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.

  12. 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.

    Patch Changes

    Platforms and environments

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

  13. 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.

    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.

  14. 12.8.0

    28 September 2026

    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.

  15. 12.7.0

    25 September 2026

    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.

  16. 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.

    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.

  17. 12.5.1

    18 September 2026

    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.

  18. 12.5.0

    18 September 2026

    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.

    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.

  20. 12.4.1

    10 September 2026

    pnpm 12.4.1 fixes installs that failed on filesystems refusing hard links or clones, on Android, and under nodeLinker: hoisted. Repeat installs are faster.

    Patch Changes

    Installing packages

    • pnpm install no longer fails with Operation not permitted when the filesystem refuses a hard link or a copy-on-write clone #14722. Under packageImportMethod: auto and clone-or-copy, pnpm copies the file instead. EdenFS checkouts, which have no hard links, and rootless containers, which refuse the clone syscall, both hit this. An explicit packageImportMethod: hardlink or clone still reports the error.

      pnpm also copies a package file whose store entry has reached the filesystem's limit on names for one file, 1024 on NTFS and 65000 on ext4. Such a file failed the install under packageImportMethod: hardlink, and under auto it stopped pnpm hard linking for the rest of the install.

  21. 12.4.0

    8 September 2026

    Minor Changes

    • pnpm can now manage npm, Python, and Cargo dependencies in the same workspace. Enable python.enabled or cargo.enabled in pnpm-workspace.yaml, then use pnpm install to install them together.

      • Add Python packages with pnpm add pypi:<package>. pnpm uses pyproject.toml, pylock.toml, and a managed .venv. Frozen and offline installs are supported, and pnpm run and pnpm exec make the environment's executables available #14566.

      • Add Rust crates with pnpm add crate:<package>. pnpm supports crates.io and custom sparse registries configured with cargo.indexUrl. Registry authentication supports pnpm credentials and, for crates.io, CARGO_REGISTRY_TOKEN or $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.

    • Added pnpm pipeline [name] to install frozen dependencies and run workspace tasks declared in pipelines. It selects affected projects, runs their task graph, and continues running tasks after a task fails.

      Tasks support inputs, outputs, env, and cache settings. Cached results restore task outputs and replay logs. Cargo tasks can reuse local build state between worktrees with tasks.<name>.cargoTargetDir. Set includeWorkspaceRoot: true to include root tasks.

      Use pnpm pipeline --dry-run to 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.

  22. 12.3.4

    4 September 2026

    Patch Changes

    • Sped up dependency resolution in large workspaces #14352.

    • pnpm 12 now accepts the boolean settings as command-line flags on every command that takes them in pnpm 11, for example pnpm install --unsafe-perm, pnpm add foo --offline, and pnpm install --dangerously-allow-all-builds. pnpm 12 rejected them with unexpected argument, which failed every install on Vercel, whose build runs pnpm install --unsafe-perm #14346.

      pnpm remove now accepts --unsafe-perm, the same flag pnpm install, pnpm add, and pnpm update take.

  23. 12.3.3

    4 September 2026

    Patch Changes

    • Fixed concurrent installs sharing a store occasionally failing with an ENOENT error while importing a package file #14353.

    • Sped up writing the lockfile in large workspaces #14352.

    • Sped up dependency resolution in large workspaces #14352.

  24. 12.3.2

    4 September 2026

    Patch Changes

    • security

      pnpm audit --fix update no longer aborts when a vulnerable package has no safe version inside its declared range #14508. The run updates every package it can and lists the rest as remaining.

    • pnpm install no longer reruns root lifecycle scripts when the global virtual store contains an unfinished-build marker in a package slot that the current lockfile does not use pnpm/pnpm#14485.

    • Sped up installs that have no lockfile. pnpm now links packages whose dependency subtree has no peer dependencies into the virtual store while resolution is still running.

  25. 12.3.1

    3 September 2026

    Patch Changes

    • Sped up installs in large workspaces: the anchor for re-rendering workspace link: targets is now derived once per project instead of once per dependency edge, and project ordering hashes paths by their raw bytes #14352.

    • After a self-update from pnpm 12.2 to 12.3, global commands such as node, npm, and yarn failed with unexpected argument '--shim' found. Global commands now launch normally, and their first launch migrates the global bin directory to native shims. When self-update downgrades to pnpm 12.2 or older, it keeps the newer native shims so those commands continue to work.

    • Sped up installs in large workspaces. The check that verifies each project against the lockfile now runs the projects in parallel #14352.

  26. 12.3.0

    2 September 2026

    Minor Changes

    • Every context-aware global command (node, deno, bun, and the shims created with pnpm shim add) is now a native executable on every platform, so environment variables whose names are not valid shell identifiers reach these commands. On Windows, <name>.exe replaces the .cmd and .ps1 shims for them. Shims written by earlier pnpm 12 releases are migrated on the next global install or self-update.

    • pnpm remove and pnpm update now accept --trust-lockfile, --no-trust-lockfile, --trust-policy, --trust-policy-exclude and --trust-policy-ignore-after, the same flags pnpm install and pnpm add take, so the supply-chain settings can be overridden for a single run. pnpm remove verifies the lockfile against the active policies the way pnpm install does, and --trust-lockfile skips that pass for every entry, not only the package being removed.

      pnpm now also honors --config.trust-lockfile=<value>, and accepts the bare --trust-lockfile / --no-trust-lockfile spelling on the commands that previously took the setting from the config file alone.

    Patch Changes

  27. 12.2.1

    1 September 2026

    Patch Changes

    • Restored the pnpm executable target without a file extension so pnpm 12.1 and earlier can upgrade to newer pnpm 12 releases on POSIX systems.

  28. 12.2.0

    31 August 2026

    Minor Changes

    • Catalogs can now resolve workspace dependencies through the workspace: protocol.

    Patch Changes

    • security

      Fixed pnpm audit --fix failing with ERR_PNPM_INVALID_FIX_OPTION when used without a value, including when another flag follows it, as in pnpm audit --fix --json #13261. Fixed pnpm audit --fix=override ignoring the saveExact and savePrefix settings when writing vulnerability overrides #11523.

  29. 12.1.0

    29 August 2026

    Minor Changes

    • pnpm login and pnpm adduser now record the granted token in the global config.yaml, under the _auth setting, with --scope's scope routed to that registry under registries. pnpm logout removes it from there, and still from an auth.ini an earlier version wrote. Tokens already in auth.ini keep working.

    • A scope set in a project's pnpm-workspace.yaml is now ignored, with a warning naming where to set it instead. pnpm login records the scope as a @scope:registry route in the machine-global auth.ini, which outranks ~/.npmrc in every project — so a repository-committed file could redirect a scope such as @acme for all of a user's other projects after one routine login. Use --scope, the PNPM_CONFIG_SCOPE environment variable, or the global config file instead #13557.

    • Verified remote build artifacts are persisted in the shared store with their signed origin metadata. Later installs reverify the artifact against current trust, policy, platform, and source before reuse, while invalid remote variants are quarantined per channel (pnpm/pnpm#13771).

  30. 12.0.0

    26 August 2026

    Major Changes

    • breaking

      Git dependencies on known hosts (GitHub, GitLab, Bitbucket) are now treated as identities rather than transport choices. Every representation of the same repository — github:owner/repo, owner/repo, git+https://…, git+ssh://git@… — resolves through the host's canonical HTTPS URL, and the lockfile never records an SSH URL for them. Repositories whose archive endpoint is anonymously reachable resolve to the host's archive (fast tarball download); all others resolve to a git clone of the canonical HTTPS URL, which every machine with access to the repository can fetch.

      To reach a private hosted repository over SSH, configure the machine (not the project) with git's own URL rewriting, for example:

      git config --global url."git@github.com:".insteadOf https://github.com/

      pnpm shells out to git, so the rewrite applies to all of pnpm's git operations automatically. URLs of unknown hosts (self-hosted servers) are unaffected and keep their exact URL, including SSH. URLs with embedded credentials are also kept verbatim and never resolve to a host archive.

      This removes the network probing that previously decided between HTTPS and SSH at resolution time, which could record a transport that only worked on the machine that happened to run the resolution (e.g. an SSH URL that broke CI runners without SSH keys).

    • breaking

      A project's pnpm-workspace.yaml may no longer carry a setting pnpm does not recognize. Such a setting used to be ignored in silence — a misspelled minimumReleaseAge dropped the policy it was meant to set, and nothing said so. Now it is reported, suggesting the closest real setting name when the key looks like a typo, and it fails the command with ERR_PNPM_UNRECOGNIZED_WORKSPACE_SETTINGS when the project pins a pnpm version the running pnpm satisfies: with the pin honored, the setting cannot be meant for a different pnpm version, so it is a mistake to fix rather than a key to ignore. Everywhere else it is a warning, so a project that has yet to be cleaned up keeps working.

      The pnpm config subcommands never fail on such a setting, so a broken file can still be inspected and repaired, and pnpm config get <key> prints the value with no warnings at all. Keys the global config file cannot set are likewise split between workspace-only settings (still directed to pnpm-workspace.yaml) and settings unknown to this version.

    • breaking

      Dependency cycles are now broken canonically during peer resolution: the members of each cycle are ordered by package id, and the edges that close a cycle are always cut at the same place, no matter where the installation walks into the cycle from. Previously the cut depended on the walk path, so installing the same dependencies could produce different lockfiles depending on importer order or resolution order #13846, and a peer-resolution verdict computed for one occurrence of a cyclic package could be wrongly reused at another #13865.

      With canonical cycle breaking the lockfile is a pure function of the dependency graph: repeated installs, reordered importers, and reordered dependencies all produce byte-identical lockfiles. Peer dependencies of packages inside a cycle keep nearest-wins resolution along the canonical order, and a dependency edge that closes a cycle references an occurrence of its target resolved at the importer level. On large cycle-heavy workspaces peer resolution is 2–3× faster, uses about 25% less memory, and produces a substantially smaller lockfile (fewer redundant peer variants).

      Existing lockfiles keep working: headless (--frozen-lockfile) installs consume them unchanged, and installs that skip resolution leave them untouched. The first install that actually re-resolves (for example after a dependency change) re-keys walk-order-dependent peer variants of cyclic packages once.

  31. 11.28.6

    15 October 2026

    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.

  32. 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.

    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.

  33. 11.28.4

    3 October 2026

    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.

  34. 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.

    Patch Changes

    Installing packages

    • security

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

  35. 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.

    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.

  36. 11.28.1

    28 September 2026

    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.

  37. 11.28.0

    25 September 2026

    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.

  38. 11.27.1

    20 September 2026

    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.

  39. 11.27.0

    12 September 2026

    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

  40. 11.26.0

    6 September 2026

    Minor Changes

    • Catalogs can now resolve workspace dependencies through the workspace: protocol.

    • pnpm remove and pnpm update now accept --trust-lockfile, --no-trust-lockfile, --trust-policy, --trust-policy-exclude, and --trust-policy-ignore-after. pnpm remove checks the whole lockfile against the active policies unless --trust-lockfile is set.

    • Added pnpm change check for CI validation of package versions against the versioning.epics bands and versioning.fixed groups in pnpm-workspace.yaml.

  41. 11.25.0

    29 August 2026

    Minor Changes

    • Added an opt-in proof of concept that lets installs reuse a dependency's build output across machines, by publishing and restoring signed, organization-scoped artifacts through pnpr instead of running the lifecycle scripts locally.

      Configure it with the new remoteSideEffectsCache setting. A workspace names the eligible organization and packages; everything describing the act of signing — publish, keyId, builderId, trustedKeys, privateKey and the provenance fields — is refused in pnpm-workspace.yaml and read from the global config file or the environment instead.

    • Added macOS and Windows x64 and arm64 support to remote shared build artifacts pnpm/pnpm#13771.

    • Added the audit.ignorePrune setting. When set to true, pnpm audit --fix removes ignored GHSA entries that no longer appear in the audit report.

  42. 11.24.0

    24 August 2026

    Minor Changes

    Patch Changes

    • Fixed pnpm v11 incorrectly reporting confirmModulesPurge as unrecognized when set in pnpm-workspace.yaml. The Rust CLI now identifies the unsupported option as a pnpm v11 setting instead of suggesting an unrelated setting.

  43. 11.23.0

    23 August 2026

    Minor Changes

    • pnpm config get and pnpm config list now show the settings pnpm acts on under their documented names:

      • registries shows the registries pnpm resolves from, merged across every source (.npmrc, pnpm-workspace.yaml, the global config, CLI flags), in the shape the setting is written in: keyed by registry URL, with the default registry declared as the bare @ scope. Built-in routes are included — the @jsr scope and the npmjs and gh prefixes — unless pointed elsewhere. Previously pnpm config get registries printed undefined.

      • update and audit show the effective sections, whichever spelling set them. The deprecated internal spellings (updateConfig, auditConfig, auditLevel) are no longer listed.

      • catalogs shows the complete resolved catalog set — the singular catalog block is its default entry — whichever spelling declared it.

      • The registry and @scope:registry entries show the merged routes rather than raw .npmrc values, so they always agree with the registries view.

    • Settings that no supported pnpm version recognizes get their own warning. A key in the global config file that this version of pnpm does not read is no longer reported with advice to move it to a project-level pnpm-workspace.yaml (where it would be ignored too); the warning now says the setting is not recognized by this version of pnpm, names the pnpm version that does read it when there is one (for example, globalShims is a pnpm v12 setting), and suggests the closest real setting name when the key looks like a typo. Unrecognized and non-camelCase keys in a project's pnpm-workspace.yaml, previously ignored silently, are now reported the same way. pnpm config get <key> and pnpm get <key> no longer print config-load warnings, so a script capturing the value gets the value alone.

    • deprecated

      The importPackage pnpmfile hook is deprecated. pnpm now prints a warning when a pnpmfile defines it, and the hook will be removed in the next major version. It also opts the installation out of the parallel package importer, making installation slower. If you rely on this hook, comment on #14101.

  44. 11.22.0

    15 August 2026

    Minor Changes

    • Added pnpm cache path, which prints the directory pnpm uses for its metadata cache. CI setups can use it to cache that directory — including the lockfile verification log, which lets a job skip re-checking an unchanged lockfile against the configured supply-chain policies.

    • --config.config-dir no longer reaches the config through a project's pnpm-workspace.yaml, and neither do the --config. spellings of the other settings a project manifest may no longer contribute (--config.pnpm-home-dir, --config.workspace-dir, --config.global-pkg-dir, --config.root-project-manifest-dir). None of them was ever a supported way to set those directories: pnpm resolves them from the environment, and these flags took effect only because the project-manifest merge re-applied the command line afterwards. The dedicated flags, such as --dir and --global-dir, are unaffected #13629.

    • pnpm config set refuses to write a setting to a project's pnpm-workspace.yaml that pnpm does not read from there, rather than leaving a key in the file that does nothing. Those settings are configDir, pnpmHomeDir, stateDir and the others that name machine-level state. The command fails with ERR_PNPM_CONFIG_SET_NOT_A_PROJECT_SETTING, naming where the setting does belong when it belongs somewhere. pnpm config delete still clears one that a file already carries, in whichever spelling it uses #13629.

  45. 11.21.0

    9 August 2026

    Minor Changes

    • Added interactive group selection to pnpm update --global --interactive.

    • Running pnpm setup, pnpm self-update, or a command that modifies the global installation (such as pnpm add --global) through sudo now prints a warning. pnpm keeps global packages and configuration in the invoking user's home directory, so running these commands as root silently operates on the root user's home directory instead of yours. They will fail with ERR_PNPM_SUDO_NOT_SUPPORTED in pnpm v12. Read-only global commands (such as pnpm bin --global) are unaffected.

    Patch Changes

  46. 11.20.0

    3 August 2026

    Minor Changes

    • security

      Security fix. Affects projects using namedRegistries on pnpm 11.1.0–11.19.x. It is semi-breaking for those projects — see "If you use named registries" below.

      The lockfile recorded no marker for which registry a package came from. Packages were keyed by name@version alone, and entry lookup went through refToRelative(ref, name), so a dependency you declared against one registry could be satisfied by an entry that was actually resolved from another. When two registries served the same name and version, both collapsed onto a single packages: entry and whichever resolved first decided the tarball every consumer got.

      That is a package-substitution risk: a package you expect from your private registry could be installed from a different registry that publishes the same name and version, and the lockfile recorded nothing that would let you tell.

      Packages resolved from a named registry are now recorded under registry-qualified keys (<name>@<registryName>:<version>, e.g. foo@work:1.0.0), so each registry gets its own entry and the lockfile pins which one a dependency came from.

      The lockfile format version is unchanged. Registry-qualified keys appear only for packages resolved from a named registry, so a project that does not use namedRegistries sees no difference, and older pnpm versions keep reading the file.

    If you use named registries

    Your next non-frozen install re-keys those entries, which shows up as a lockfile diff. Commit it — that diff is the fix being applied. Review it: an entry that moves to a registry you did not expect is worth investigating.

  47. 11.19.0

    31 July 2026

    Minor Changes

    • pnpm login no longer requires an interactive terminal when the registry supports web-based login: without a TTY it prints the authentication URL (skipping the QR code and the "Press ENTER to open the URL in your browser" prompt) and polls the registry until the browser approval completes. Only the classic username/password login still fails with ERR_PNPM_LOGIN_NON_INTERACTIVE in a non-interactive terminal.

    • The save-prefix setting now accepts =: newly added dependencies are saved with an explicit = operator (=1.2.3) instead of the setting being silently treated as the default ^.

    Patch Changes

  48. 11.18.0

    29 July 2026

    Minor Changes

    • Fixed an installed optional dependency being left without one of its own required dependencies. When a package reached through optionalDependencies is installable on the current system but one of its regular dependencies is not, a lockfile-based install skipped that dependency and installed the parent anyway, so importing the parent failed with MODULE_NOT_FOUND. The dependency is now installed, and an install-check warning reports the incompatibility. A dependency is still only skipped when every path to it is optional, or when the package that pulls it in was itself skipped #13286.

    • pnpm setup now appends PNPM_HOME and the global bin directory to the GitHub Actions environment files (GITHUB_ENV and GITHUB_PATH), so later steps in the same job can run pnpm add --global and other global commands #9191.

    • Added support for publishConfig.name, which publishes a package under a different name than the one its manifest carries in the workspace. It is for a project whose published name is already taken by a sibling project, which otherwise has to be renamed by a build step just before publishing. Only the published artifact is renamed — dependents, pnpm-lock.yaml, and release tooling keep addressing the project by its manifest name — and the new name reaches the packed manifest, the tarball filename, and everything that addresses the package at the registry: the already-published check of pnpm publish -r, its registry selection, and the release-planning probes of pnpm change status and pnpm version -r #13345.

  49. 11.17.0

    23 July 2026

    Minor Changes

    • Added a new setting, update.githubActionsServer, for specifying the base URL of the GitHub server that hosts the repositories of the GitHub Actions referenced by the workflow files (for example, a GitHub Enterprise Server). When the setting is not defined, the URL is read from the GITHUB_SERVER_URL environment variable, falling back to https://github.com. The URL must use the https:// or http:// protocol #13220.

      pnpm outdated and pnpm update no longer fail when the refs of a GitHub Action's repository cannot be read (for example, when the action's repository is private or hosted on a different GitHub server). Such actions are now skipped with a warning.

      Setting update.githubActions to false now makes pnpm outdated and the interactive pnpm update skip GitHub Actions dependencies.

    Patch Changes

    • The token poll for web-based authentication no longer reads the body of non-OK or still-pending (HTTP 202) responses, and caps the token response body it does read at 64 KiB, so a malicious or compromised registry cannot exhaust memory through the poll pnpm/pnpm#12721.

  50. 11.16.0

    22 July 2026

    Minor Changes

    • The first release of a package now publishes the version written in its manifest verbatim, instead of bumping off it. pnpm version -r and pnpm change status check the registry for each release's current version; when that version is not yet published, the package debuts at it and its pending changesets apply only from the next release. A newly added package seeded at 1100.0.0 with a minor changeset is therefore published as 1100.0.0 rather than skipping straight to 1100.1.0.

    • Added a --changeset flag to pnpm update. Set update.changeset to true in pnpm-workspace.yaml to enable this behavior by default, and use --no-changeset to override the setting for one update. After the update completes, pnpm writes a .changeset/pnpm-update-<suffix>.md file declaring a patch bump for every workspace package whose dependencies or optionalDependencies were changed by the update and a major bump when peerDependencies changed, including packages that consume an updated catalog entry via the catalog: protocol. Private packages, packages without a name, and packages listed in the ignore array of .changeset/config.json are skipped. If .changeset/config.json does not exist, a warning is printed and no changeset is generated.

    • Added GitHub Actions dependencies to pnpm outdated and interactive pnpm update. Non-interactive updates can include them with --include-github-actions or by setting update.githubActions to true in pnpm-workspace.yaml. Updated actions are pinned to exact commit hashes with their release tags preserved in comments.