Packages

@pnpm/exe

12.14.0 · 15 Oct 2026MIT4.3M / weekRepositoryHomepagenpmAtom feed

436 stable releases, newest first, by release line. Notes are quoted as the maintainers published them.

  1. 12.x · latest line
  2. 12.14.0

    15 Oct 2026
    • Added the sideEffectsCache.exclude setting for packages whose build depends on something pnpm cannot include in the cache key, such as the system libraries a native addon links against. pnpm builds the listed packages in every project and never restores or saves their builds through the side-effects cache, locally or on a remoteCache server. Under the global virtual store, each project gets its own copy of these packages and of the packages that depend on them. Entries use the same name, @scope/*, and name@version patterns as minimumReleaseAgeExclude #5271.

    • pnpm login now prints the npm-notice response header during web-based login. Registries use it to show the verification code that completes the sign-in in the browser.

    • pnpm install and pnpm add no longer wait for the daily update check. If the command finishes first, pnpm skips the update notice and checks again next time. On a registry that accepted the connection but never answered, an install that had nothing to do used to take minutes #16839.

  3. 12.13.0

    13 Oct 2026
    • Added the pnpm profile command to view and update registry user profile settings.

    • Added pnpm token to list, create, and revoke authentication tokens on the registry.

    • Added the storeIndexFormat setting. Set it to files to keep a store's package index as one file per package instead of the SQLite index.db, for a store on a network filesystem that several machines use at once. SQLite's locking does not work across machines, so concurrent installs on such a store could corrupt index.db.

  4. 12.12.1

    11 Oct 2026
    • 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.

  5. 12.12.0

    10 Oct 2026
    • 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.

  6. 12.11.2

    9 Oct 2026
    • --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.

  7. 12.11.1

    9 Oct 2026
    • 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.

  8. 12.11.0

    9 Oct 2026
    • 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.

    • 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:

  9. 12.10.1

    6 Oct 2026
    • 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".

  10. 12.10.0

    6 Oct 2026
    • security

      pnpm install now prevents dependency versions with path traversal from writing files outside the global virtual store.

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

  11. 12.9.1

    3 Oct 2026
    • 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.

  12. 12.9.0

    2 Oct 2026
    • pnpm now automatically uses WebAssembly in StackBlitz WebContainers, including when installation scripts are disabled. Native installations continue to use the native executable when installation scripts are enabled.

    • A registries entry can now set networkConcurrency, the most requests pnpm keeps in flight to that registry's origin. Requests to other registries keep the overall limit. The setting may live in pnpm-workspace.yaml or the global config.yaml.

      registries:
        https://npm.corp.example.com/:
          scopes: ["@acme"]
          networkConcurrency: 4
    • pnpm install now records every project it installs in the store's projects directory, as a symlink to the project directory. A --frozen-store install without the global virtual store still records nothing. Only projects that used the global virtual store were recorded before #6929.

  13. 12.8.2

    30 Sep 2026
    • 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.

  14. 12.8.1

    28 Sep 2026
    • 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.

  15. 12.8.0

    28 Sep 2026
    • deprecated

      pnpm add --save-types no longer adds a @types/* package whose resolved version is deprecated. DefinitelyTyped publishes such stubs for packages that ship their own types, such as @types/typescript for typescript #15636.

    • pnpm pack and pnpm publish now warn when the tarball includes a .env or .env.* file that the files field of package.json does not list. Templates such as .env.example are not reported. List the file in files to publish it on purpose, or exclude it in .npmignore or .gitignore #7826.

    • pnpm pack now honors --silent, --reporter=silent, and --loglevel=silent to hide the tarball contents and summary. With --json, lifecycle script output and the final JSON output remain visible #10297.

  16. 12.7.0

    25 Sep 2026
    • security

      pnpm no longer expands environment variables in a userAgent set in a project's pnpm-workspace.yaml. A userAgent with a placeholder in that file is now ignored. Before this fix, pnpm sent the variable's value to the configured registry #15415.

    • security

      On Nix, a dependency's bin named like a system utility such as sed can no longer redirect a POSIX bin shim or the pnpm, pn, pnpx, and pnx launchers. The shims and launchers now ignore node_modules and relative PATH entries while they locate their own files. Installing again replaces the shims already in node_modules #14883.

    • security

      pnpm no longer treats manifests inside its store, cache, state, or modules directories as workspace projects. Before, a storeDir inside the workspace could let lifecycle scripts of packages in the store run without allowBuilds approval #15033.

  17. 12.6.0

    22 Sep 2026
    • 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.

  18. 12.5.1

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

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

  19. 12.5.0

    18 Sep 2026
    • pnpm add accepts a Package URL in place of a package name. pnpm add pkg:npm/express@4.18.2 saves express to package.json. pnpm add pkg:cargo/serde@1.0.188 saves serde to Cargo.toml. pnpm add pkg:pypi/requests@2.31.0 saves requests to pyproject.toml. pkg is now a reserved specifier prefix, whatever case it is written in, so a named registry can no longer be called pkg.

    • A registries entry can now name the ecosystem it serves.

      registries:
        https://internal.example/simple/:
          ecosystem: pypi
        https://pypi.org/simple/:
          ecosystem: pypi
        https://index.crates.io/:
          ecosystem: cargo

      ecosystem accepts npm, cargo and pypi. An entry that does not name one serves npm, as every entry did before.

      An ecosystem with several indexes searches them in the order they are declared. The first index that has a package supplies it, so the one declared last answers what none before it had.

      A registries entry may not carry credentials. pnpm reads them from .npmrc, matched by origin, for a PyPI index as for every other package source.

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

  20. 12.4.2

    15 Sep 2026
    • 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.

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

  21. 12.4.1

    10 Sep 2026
    • 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.

    • pnpm install no longer writes a package file through a symlink left at the path it is importing to. Copying such a file overwrote whatever the link pointed at, and created that file when the link pointed nowhere. An executable package file also made the link's target executable.

    • Fixed pnpm install and pnpm dlx on Android. Registry requests crashed because pnpm found no system CA certificates, so pnpm uses bundled ones there #14777. Imports also failed with "Permission denied" on filesystems that deny hard links and reflinks, and now fall back to copying #14780.

  22. 12.4.0

    8 Sep 2026
    • 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.

      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.

  23. 12.3.4

    4 Sep 2026
    • 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.

  24. 12.3.3

    4 Sep 2026
    • 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.

  25. 12.3.2

    4 Sep 2026
    • 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.

  26. 12.3.1

    3 Sep 2026
    • 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.

  27. 12.3.0

    2 Sep 2026
    • 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.

    • pnpm add <local directory>, pnpm add <local tarball>, pnpm add file:<path> and pnpm add <tarball URL> work again. A specifier given without a <name>@ prefix is no longer read as a registry package name and rejected with ERR_PNPM_PACKAGE_MANAGER_ADD_RESOLVE_LATEST #14437.

  28. 12.2.1

    1 Sep 2026
    • 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.

  29. 12.2.0

    31 Aug 2026
    • 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.

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

    • Authenticate Node.js runtime downloads from nodeDownloadMirrors with URL-scoped npm registry credentials, including bearer tokens, basic auth, and tokenHelper pnpm/pnpm#14334.

  30. 12.1.0

    29 Aug 2026
    • 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).

  31. 12.0.0

    26 Aug 2026
    • 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.

  32. 11.x
  33. 11.28.6

    15 Oct 2026
    • security

      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.

    • security

      The warning about renamed package files with invalid names no longer prints control characters from those file names.

    • pnpm again accepts httpProxy and httpsProxy set to null or written with no value in pnpm-workspace.yaml and the global config file, and treats them as unset. Since 11.28.5 these values failed with ERR_PNPM_INVALID_SETTING.

  34. 11.28.5

    6 Oct 2026
    • 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.

  35. 11.28.4

    3 Oct 2026
    • pnpm login no longer forwards credentials in its request body to another origin during redirects.

    • The error for a tarball that fails its integrity check no longer prints credentials, query strings, or fragments from the tarball URL.

    • pnpm install --frozen-lockfile now succeeds in a project with no dependencies when pnpm-lock.yaml records only the pinned pnpm version. Other commands write such a lockfile when they run before the first install. A lockfile missing the --- line after that section is accepted too #16477.

  36. 11.28.3

    30 Sep 2026
    • 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:

  37. 11.28.2

    28 Sep 2026
    • 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.

  38. 11.28.1

    28 Sep 2026
    • pnpm install now works in StackBlitz WebContainers. On projects without a lockfile, it used to fail with ENOENT ... pnpm-lock.yaml, because pnpm did not recognize the errors that WebContainers return from asynchronous file system calls. It also failed with "this.db.exec is not a function", because node:sqlite there lacks DatabaseSync.exec. When node:sqlite cannot prepare statements either, pnpm stores the index in index.fallback #15649.

    • pnpm install now completes after downloading a Node.js runtime specified by devEngines.runtime when pnpm runs on Node.js 24.4.x #14667.

    • pnpm install no longer fails when a package from the registry declares a file: dependency on a directory inside itself, such as "@types/css-tree": "file:./typings/css-tree". pnpm links that dependency to the directory inside the package, as npm and Yarn do. The lockfile records it as link:<root>/typings/css-tree #9141.

  39. 11.28.0

    25 Sep 2026
    • security

      pnpm no longer expands environment variables in a userAgent set in a project's pnpm-workspace.yaml. A userAgent with a placeholder in that file is now ignored. Before this fix, pnpm sent the variable's value to the configured registry #15415.

    • security

      pnpm no longer treats packages inside a custom modulesDir as workspace projects, including one that packageConfigs sets for a project. Before, with a modulesDir such as vendor and a packages pattern such as **, a repeat install ran the lifecycle scripts of dependencies that allowBuilds had not approved #15412.

    • security

      On Nix, a dependency's bin named like a system utility such as sed can no longer redirect a POSIX bin shim or the pnpm, pn, pnpx, and pnx launchers. The shims and launchers now ignore node_modules and relative PATH entries while they locate their own files. Installing again replaces the shims already in node_modules #14883.

  40. 11.27.1

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

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

  41. 11.27.0

    12 Sep 2026
    • 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).

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

  42. 11.26.0

    6 Sep 2026
    • security

      pnpm audit now excludes ignored advisories from vulnerability totals and severity counts, and reports them separately #14535.

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

  43. 11.25.0

    29 Aug 2026
    • 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.

  44. 11.24.0

    24 Aug 2026
    • Added global build approvals pnpm/pnpm#14101.

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

    • pnpm install --frozen-lockfile no longer fails with ERR_PNPM_FROZEN_LOCKFILE_WITH_OUTDATED_LOCKFILE when the pinned pnpm version recorded in pnpm-lock.yaml has to be re-resolved before it can be installed. It runs the pnpm version the lockfile pins and leaves the lockfile unchanged #14124.

  45. 11.23.0

    23 Aug 2026
    • 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.

    • deprecated

      pnpm audit no longer reports a patched version that was never published or is deprecated. The inferred patched range (e.g. >=4.17.24 from <=4.17.23) is now checked against the registry packument, and the report is corrected to the lowest non-deprecated published version that satisfies it (e.g. >=4.18.1 when 4.17.24 does not exist and 4.18.0 is deprecated). When no published version satisfies the range, the report shows Patched versions: None. This also prevents pnpm audit --fix from adding overrides or minimumReleaseAgeExclude entries for patches that do not exist #13824.

      pnpm audit --fix and pnpm audit --fix update no longer add a minimumReleaseAgeExclude entry when the registry packument shows that the minimum patched version was never published. Previously such entries were written for versions that do not exist, which would have let a later publish of that version bypass the minimumReleaseAge gate #11563.

      The --json output of pnpm audit now returns patched_versions: null for advisories whose inferred patch is not available (never published, skipped, yanked, or deprecated), making it easier for tooling to distinguish "no fix available" from "fix available at version X".

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

  46. 11.22.0

    15 Aug 2026
    • 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.

  47. 11.21.0

    9 Aug 2026
    • 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.

    • Fixed pnpm failing to start under asynchronous Node.js module loaders when no .pnpmfile.mjs exists pnpm/pnpm#11701.

  48. 11.20.0

    3 Aug 2026
    • 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.

    • security

      Security: pnpm rebuild now refuses a lockfile whose packages key carries a path traversal in the package name (e.g. ../../../escaped@1.0.0), instead of running that package's lifecycle scripts and linking its bins in a directory outside the virtual store. Such a name is rejected with ERR_PNPM_INVALID_DEPENDENCY_NAME.

    • An empty http-proxy, https-proxy, proxy, or no-proxy value — from the .npmrc, pnpm-workspace.yaml, the CLI, or the HTTP_PROXY / HTTPS_PROXY / PROXY / NO_PROXY environment variables — no longer fails the install with ERR_PNPM_INVALID_PROXY. Empty settings read as unset, so a shell exporting HTTP_PROXY= disables the proxy, and an empty proxy= in the .npmrc no longer suppresses HTTPS_PROXY #13533.

      proxy=false in the .npmrc or proxy: false in pnpm-workspace.yaml now turns proxying off instead of being read as a proxy host named false. false and null on https-proxy / http-proxy / no-proxy read as unset, and on the command line they are ordinary host names, since a flag carries its value verbatim.

  49. 11.19.0

    31 Jul 2026
    • 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 ^.

    • allowBuilds entries can now approve git-hosted packages that pnpm downloads as a tarball, such as github: dependencies (which are fetched from codeload.github.com rather than cloned), by their repository URL without the resolved commit hash. This matches the hashless git+ matching already supported for cloned git dependencies. For example:

      allowBuilds:
        "foo@git+https://github.com/org/foo.git": true

      This approves the package whether pnpm clones it or downloads a tarball, so the entry no longer has to be updated every time the pinned commit changes. GitLab and Bitbucket tarball downloads are matched the same way. Approving or denying a specific resolved commit by its full tarball dep path continues to work.

  50. 11.18.0

    29 Jul 2026
    • 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.

  51. 11.17.0

    23 Jul 2026
    • 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.

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

    • Fixed catalog: references in dependencies and overrides failing to resolve when installing through a pnpr server, which errored with "No catalog entry '<name>' was found for catalog 'default'." even though the catalog entry existed. Also fixed a crash on Windows when installing a nested workspace member (e.g. packages/foo) through a pnpr server #13232.

  52. 11.16.0

    22 Jul 2026

    Reading the note…