Skip to content

chore(deps): update pnpm to v11#969

Open
renovate[bot] wants to merge 1 commit into
devfrom
renovate/pnpm-11.x
Open

chore(deps): update pnpm to v11#969
renovate[bot] wants to merge 1 commit into
devfrom
renovate/pnpm-11.x

Conversation

@renovate

@renovate renovate Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
pnpm (source) 9.15.011.10.0 age confidence
pnpm (source) 1011 age confidence

Warning

Some dependencies could not be looked up. Check the warning logs for more information.


Release Notes

pnpm/pnpm (pnpm)

v11.10.0

Compare Source

Minor Changes
  • e2e3c81: Added the issues command as an alias of bugs, so pnpm issues opens the package's bug tracker URL in the browser.

  • 8491f8e: Added the prefix command which prints the current package prefix directory (or global prefix directory if -g / --global is used).

  • 3425e80: Added an _auth setting for configuring registry authentication as a single structured (URL-keyed) value. It can be set in the global pnpm config (config.yaml) or, for CI, via the pnpm_config__auth environment variable. The env form sidesteps the GitHub Actions / bash / zsh limitation that broke the existing pnpm_config_//host/:_authToken=… form (env var names containing /, :, or . are silently dropped). Closes #​12314.

    The value is keyed by registry URL so each secret is explicitly bound to the host that may receive it. Registry URL keys must use http or https and must not include credentials, query strings, or fragments:

    export pnpm_config__auth='{"https://registry.npmjs.org":{"@​":{"authToken":"npm-token"},"@​org":{"authToken":"org-token"}}}'

    The equivalent in the global config.yaml:

    _auth:
      https://registry.npmjs.org:
        "@​":
          authToken: npm-token
        "@​org":
          authToken: org-token

    Within each registry URL, @ means registry-wide/default credentials and package scopes like @org bind credentials to that scope on the same host. The only supported credential field is authToken (maps to _authToken / bearer auth); the deprecated basicAuth / username + password forms are intentionally not accepted here.

    Each entry also infers a trusted registry route: @ routes the default registry (and pnpm add <pkg> resolves there), and @org routes that scope. Because the credential and destination host arrive in one trusted value, repo-controlled pnpm-workspace.yaml or project .npmrc cannot redirect the token to a different host. _auth is honored only from the env var and the global config — it is ignored in a project pnpm-workspace.yaml / .npmrc, so repo-controlled config can never supply registry auth. Precedence: CLI flags (--registry, --@&#8203;scope:registry) > pnpm_config__auth > global config.yaml _auth > pnpm-workspace.yaml.

    Both pnpm_config__auth (lowercase, documented form) and PNPM_CONFIG__AUTH (all-caps, the shell convention some CI runners apply) are honored. If both are set, lowercase wins unless it is empty, in which case uppercase is used. The env var wins over the global config.yaml _auth on a conflicting key. tokenHelper is not supported in _auth. Parsing is strict: a malformed value (bad JSON, wrong shape, invalid registry URL or scope, an unsupported credential field) fails fast with an error rather than being silently dropped.

    Pacquet parity note: the pacquet (Rust) port supports the same single credential field as the TS CLI: authToken.

  • a33eeec: pnpm self-update and packageManager version-switching can now install and link pnpm v12 (the Rust port), published with equal content under both the pnpm and @pnpm/exe names on the next-12 dist-tag. Its native binaries ship as @pnpm/exe.<platform>-<arch> packages, which pnpm's built-in installer links directly — no Node.js launcher, so the command pays no Node startup cost. v12 is initialized exactly like @pnpm/exe, including per-platform global-virtual-store hashing. From v12 onward the install converges on the unscoped pnpm package (the Rust exe) — even when updating from the SEA @pnpm/exe build.

  • 1dd12bd: When resolving through a pnpr install-accelerator server, pnpm no longer forwards its own upstream registry credentials in the resolve request. Only the Authorization header identifying the caller to pnpr is sent. The pnpr server now selects upstream credentials from its own route policy (operator-configured upstream credential aliases), so private dependencies resolve through a pnpr-managed alias the caller is authorized to use, rather than by sending the client's registry tokens to the server.

  • 1e81761: Expose web authentication authUrl and doneUrl in JSON error output when OTP is required in a non-interactive terminal #​12724.

Patch Changes
  • 2f389d6: Added the Node.js release team's new signing key (Stewart X Addison, 655F3B5C1FB3FA8D1A0CA6BDE4A7D232B936D2FD) to the embedded Node.js release keys, so runtimes whose SHASUMS256.txt is signed by the new releaser verify successfully.

  • acbdb94: Fixed shell tab completion not suggesting workspaces after the -F alias for --filter option.

  • dcabb78: Fixed pnpm up -r <pkg> bumping unrelated packages that have open semver ranges. Previously, any update mutation nullified the lockfile-derived preferredVersions globally, so packages with ^x.y.z ranges could re-resolve to newer compatible versions even though the user only asked to update a specific package. The install layer now always seeds preferredVersions from the lockfile, and caller-supplied preferred versions (such as the vulnerability penalties of pnpm audit --fix) layer on top of the seed instead of replacing it. The targeted package still bumps: the per-resolve updateRequested flag makes the resolver ignore the target's own lockfile pins.

    Closes #​10662.

  • d539172: Fixed pnpm pack and pnpm publish failing when prepack generates files that are included in the package and postpack cleans them up.

  • be6505a: Hardened global package management:

    • On Windows, removing or updating a global package now also cleans up the node.exe flavor of a bin, so a stale node.exe no longer survives on PATH after uninstall, and a new global install no longer silently overwrites an existing node.exe.
    • pnpm add -g pnpm@<version> (and @pnpm/exe@<version>) is now rejected like the bare pnpm form, pointing to pnpm self-update.
    • Dependency aliases read from a global package's manifest are validated before being joined onto node_modules paths, preventing a tampered manifest from escaping the install directory.
    • Each global install group is created in its own freshly-made directory (no longer reusing a colliding or pre-existing path).
    • Removing or updating a global package no longer unlinks a bin that belongs to a different globally installed package.
  • 25c7388: pnpm now rejects jsr: specifiers whose package name is not a valid npm package name — an empty scope or name (e.g. jsr:@&#8203;scope/), path separators inside the name, or any other shape validate-npm-package-name rejects — with ERR_PNPM_INVALID_JSR_PACKAGE_NAME instead of silently converting them into a malformed @jsr/... npm package name.

  • 25c7388: pnpm now rejects named-registry specifiers (e.g. gh:) whose package name is not a valid npm package name — an empty scope (e.g. gh:@&#8203;/bar), path separators inside the name (e.g. gh:@&#8203;scope/../name), or any other shape validate-npm-package-name rejects — with ERR_PNPM_INVALID_NAMED_REGISTRY_PACKAGE_NAME instead of passing the name through to registry URLs and metadata cache file paths.

  • 96da7c5: node-gyp's gyp_main.py and gyp entrypoints are now packed with the executable bit in the pnpm and @pnpm/exe tarballs. Without it, building native addons from source could fail with a permission error.

  • 99982b9: Sped up resolution and reduced memory use against registries that ignore npm's abbreviated metadata format and always return the full package document (for example, Azure DevOps Artifacts). pnpm now strips such documents down to the abbreviated field set before caching them. Resolution output is unchanged, and registries that honor the abbreviated format (such as the npm registry) pay no extra cost.

  • 11a7fdd: Sped up offline and --prefer-offline resolution on large workspaces (e.g. pnpm dedupe --offline, pnpm install --offline). Package metadata loaded from the local cache is now kept in memory, so each package's metadata is parsed once per command instead of once per dependent that references it.

  • 2c7369d: pnpm pack-app now rejects --entry / pnpm.app.entry and --output-dir / pnpm.app.outputDir values that are absolute paths or escape the project directory via .. (or a symlink that resolves outside it), and refuses to write the produced executable when its target path already exists as a symlink (or other non-regular file). This prevents a repository-controlled package.json from embedding host files (such as an SSH key) into the produced executable, writing build artifacts outside the project, or overwriting an arbitrary file through a committed symlink. The new error codes are ERR_PNPM_PACK_APP_ENTRY_OUTSIDE_PROJECT, ERR_PNPM_PACK_APP_OUTPUT_DIR_OUTSIDE_PROJECT, and ERR_PNPM_PACK_APP_OUTPUT_FILE_NOT_REGULAR.

    When ad-hoc signing macOS targets, pnpm pack-app now runs the system codesign by absolute path and resolves ldid to a location outside the project, so a repository-controlled node_modules/.bin on PATH cannot hijack the signer.

  • ce5d5a5: Relative paths in patchedDependencies are now resolved against the lockfile directory when computing patch file hashes, so running pnpm install from a subdirectory no longer fails with ENOENT looking for the patch file in the wrong location #​12762.

  • ebb4096: pnpm peers no longer reports a conflict for a missing peer dependency that is ignored via pnpm.peerDependencyRules.ignoreMissing.

  • dcabb78: Fixed a prototype-pollution hazard when seeding preferred versions: a dependency named __proto__ in a manifest or in pnpm-lock.yaml could write through Object.prototype (or crash the install) while the preferred-versions map was being built. The maps are now null-prototype objects, so crafted package names land as plain keys.

  • f38e696: Hardened pnpm deploy --force so it refuses unsafe deploy targets such as workspace roots, parent directories, out-of-workspace paths, and symlinked target parents.

  • 806c3ec: pnpm no longer warns about ignored project-level auth settings when PNPM_CONFIG_NPMRC_AUTH_FILE points at the project .npmrc — setting it to that file is an explicit opt-in to trusting it, so auth env variables in it are expanded pnpm/pnpm#12480.

  • 991405e: Restore differential rendering (ansi-diff) to fix duplicated output lines introduced by #​12351.

  • c121235: Fixed the topological order of --filtered commands (pnpm run, pnpm exec, pnpm publish, pnpm pack, pnpm rebuild) when the selected projects depend on each other only transitively through projects that were not selected. Previously such selected projects could run concurrently or in the wrong order; now a project always runs after the selected projects it transitively depends on, while projects without a real dependency relationship still run concurrently. This now also holds for prod-only filters (--filter-prod), which resolve order through the production dependency graph so transitive production dependencies are respected without pulling back the dev dependencies the filter drops, and for selections that mix --filter with --filter-prod #​8335.

  • d539172: pnpm pack and pnpm publish no longer follow a symlinked workspace LICENSE file when injecting it into a package that has no license of its own. Following the symlink could pack bytes from outside the workspace into the published tarball.

  • dcabb78: Fixed pnpm up <pkg> producing a different result than a fresh install of the same manifests would. The resolver now distinguishes updateRequested (true only for packages that match the user's update target) from the broader update flag, and for the targeted package ignores only its own lockfile-derived preferred-version pins — so the target re-resolves exactly as if its lockfile entries were deleted and pnpm install ran. Preferred versions a fresh install applies (manifest pins, versions propagated down the dependency chain, and the vulnerability-avoidance penalties of pnpm audit --fix) stay in effect, so an update never installs duplicate versions that a reinstall from scratch would not reproduce. When a preferred version holds the update target below the newest version its range admits, pnpm now prints a warning explaining that reaching the newer version everywhere requires an override.

  • dcabb78: pnpm update <dep>@&#8203;<version> now prints a warning when <dep> is only present as a transitive dependency: the requested version cannot be applied there (updates resolve the target the way a fresh install would), and the warning recommends adding the version to pnpm.overrides instead, which is the mechanism that does pin transitive dependencies. Closes #​12744.

  • a6c4d5f: When a dependency cannot be found in the registry (404) or the registry has no matching version, and a workspace project with the same name exists only at non-matching versions, the error now reports the available workspace versions (ERR_PNPM_NO_MATCHING_VERSION_INSIDE_WORKSPACE) instead of the raw registry failure pnpm/pnpm#1379. Other registry failures (authorization, network, server errors) still propagate unchanged. The pacquet (Rust) resolver applies the same behavior.

v11.9.0

Compare Source

Minor Changes
  • bae694f: Some registries generate tarballs on-demand and cannot provide an integrity checksum in their package metadata. In that case pnpm now computes the integrity from the downloaded tarball and stores it in the lockfile, so the entry is verifiable on subsequent installs instead of being written without an integrity (which would fail the next install). This also applies to --lockfile-only: the tarball is downloaded so its integrity can be computed. A lockfile entry that is still missing its integrity is rejected as a ERR_PNPM_MISSING_TARBALL_INTEGRITY lockfile verification violation (the install fails closed) rather than being silently re-fetched.
  • 6c35a43: Added --exclude-peers to pnpm sbom. With auto-install-peers (the default), peer dependencies resolve into the lockfile and are otherwise indistinguishable from the package's own dependencies. The flag drops peer dependencies (and any transitive subtree reachable only through them) from the SBOM. CycloneDX 1.7 has no scope or relationship that expresses "consumer-provided peer", so omission is the only spec-clean handling. The flag name matches pnpm list --exclude-peers; note the SBOM flag prunes a peer's exclusive subtree, which is stricter than pnpm list (which only hides leaf peers).
Patch Changes
  • 25a829e: pnpm audit --fix now writes a single combined minimumReleaseAgeExclude entry per package (e.g. axios@0.18.1 || 0.21.1) instead of one entry per version, matching the format documented for the setting. Existing per-version entries in pnpm-workspace.yaml are merged into the combined form rather than left as duplicates. Installs that auto-collect immature versions into minimumReleaseAgeExclude now report the same combined entries, so the "Added N entries" message matches what is written to the manifest #​12534.

  • 1cbb5f2: Fixed non-deterministic peer resolution that could add or remove an optional transitive peer — for example @babel/core, reached through styled-jsx — from a package's peer-dependency suffix across otherwise identical installs, churning the lockfile and causing intermittent pnpm dedupe --check failures in CI. When a package's children are resolved by one occurrence (the "owner") and reused by a deeper consumer, whether that consumer inherited the owner's missing peers depended on whether the owner's resolution had finished yet — a race under concurrent resolution. The decision is now a function of the dependency graph's structure rather than resolution-completion order.

  • d577eea: Fixed a Windows flakiness in pnpm dlx where a failed install could surface a spurious EBUSY: resource busy or locked error. The cleanup of a partially-populated dlx cache is now best-effort with retries and no longer masks the original error.

  • ec7cf70: Shortened the pnpm dlx cache path so deep dependency trees no longer overflow Windows' MAX_PATH, which could make a dependency's lifecycle script fail with spawn cmd.exe ENOENT.

  • 05b95ab: Fixed pnpm hanging (and crashing with an unhandled promise rejection) when a non-retryable network error such as SELF_SIGNED_CERT_IN_CHAIN occurs while fetching from a registry. The error is now rejected through the returned promise instead of being thrown inside the detached retry callback.

  • d3f68e2: Fix a pnpm audit performance regression on lockfiles that contain dependency cycles. The reachable-vulnerability pruning added in pnpm 11.5.1 only memoized acyclic subtrees, so any node whose subtree touched a cycle — together with all of its ancestors — was recomputed on every query, making the path walk quadratic. Reachability is now computed once per node using Tarjan's strongly-connected-components algorithm, so cyclic graphs are handled in linear time #​12212.

    The audit path walk also no longer recurses, so a deeply nested dependency graph can no longer overflow the call stack, and the install path to each finding is tracked without per-node copying, keeping memory linear in the graph depth.

  • 322f88f: Fix failed optional dependency updates so they don't rewrite unrelated dependency specs #​11267.

  • 1488db1: When enableGlobalVirtualStore is toggled on for a project that was previously installed without it, stale hoisted symlinks under node_modules/.pnpm/node_modules are now replaced instead of being left pointing at the old per-project virtual store location #​9739.

  • 6545793: Fixed pnpm install --ignore-workspace overwriting the allowBuilds map in pnpm-workspace.yaml. The ignored builds of a package with a build script were auto-populated into allowBuilds even though --ignore-workspace was passed, clobbering committed true/false values with the set this to true or false placeholder #​12469.

  • fbdc0eb: Fixed minimumReleaseAgeExclude and trustPolicyExclude so multiple exact-version entries for the same package behave the same as a single || disjunction entry. Previously only the first matching rule's versions were honored, so a config like [form-data@4.0.6, form-data@2.5.6] could still flag form-data@2.5.6 as violating minimumReleaseAge, while [form-data@4.0.6 || 2.5.6] worked as expected #​12463.

  • fa7004b: The in-memory package metadata cache is now populated on the exact-version disk fast path, so repeated resolutions of the same package within one install no longer re-read and re-parse the on-disk metadata. In large monorepos this brings the time for adding a new package down from minutes to seconds. The in-memory cache key now also includes the registry, so a package of the same name served by two different registries in a single install can no longer share a cache slot and resolve the wrong tarball.

  • 0a154b1: Fixed pnpm patch dropping the package name (and leaking internal option fields) when the patched dependency resolves to a single git-hosted version.

  • 4d3fe4b: The pnpr resolver endpoints moved under the reserved /-/pnpr namespace: POST /v1/resolve is now POST /-/pnpr/v0/resolve and POST /v1/verify-lockfile is now POST /-/pnpr/v0/verify-lockfile. The capability handshake at GET /-/pnpr advertises protocol version 0 to match. This keeps every pnpr-proprietary route in npm's reserved namespace, so it can never collide with a package path.

  • 0ec878d: Removing a runtime dependency now removes the matching devEngines.runtime or engines.runtime entry that was materialized from it. Blank runtime selectors are normalized to latest.

  • 17e7f2c: pnpm sbom now emits a CycloneDX issue-tracker external reference for components (and the root) whose package.json declares a bugs URL. Email-only bugs entries are skipped, since the reference requires a URL.

  • a84d2a1: Add @pnpm/resolving.tarball-url, which builds and recognizes the canonical npm tarball URL of a package. It vendors getNpmTarballUrl (previously the external get-npm-tarball-url package) and adds isCanonicalRegistryTarballUrl, the predicate the lockfile writer uses to decide whether a tarball URL is derivable from name+version+registry (and can therefore be omitted from pnpm-lock.yaml).

    Exposing isCanonicalRegistryTarballUrl lets a custom resolver (pnpmfile resolvers) fronting a proxy that serves tarballs on a non-canonical path (e.g. an ephemeral localhost:<port>) rewrite the resolved tarball to the canonical form, so nothing host-specific is persisted to the lockfile. Previously this logic was private to @pnpm/lockfile.utils.

    Two correctness fixes are included while consolidating the logic: the scoped-package unescape now handles uppercase %2F as well as %2f (percent-encoding is case-insensitive), and protocol-insensitive comparison strips only a leading http(s):// scheme instead of splitting on the first :// (which could truncate URLs containing a later ://).

  • 852d537: Lockfile verification no longer reports a registry metadata fetch failure (for example a 403/401 on a private registry, or a network error) as ERR_PNPM_TARBALL_URL_MISMATCH. When the registry can't be reached to verify an entry, the install now aborts with the registry's own fetch error (such as ERR_PNPM_FETCH_403, which already explains the authentication situation) instead of mislabeling a transport failure as lockfile tampering. Registry fetch errors no longer leak basic-auth credentials embedded in the registry URL (https://user:pass@host/) into their message.

v11.8.0

Compare Source

Minor Changes
  • c112b61: Added a --dry-run option to pnpm install. It runs a full dependency resolution and reports what an install would change, but writes nothing to disk (no lockfile, no node_modules) and always exits with code 0. This mirrors the preview semantics of npm install --dry-run #​7340.

  • 179ebc4: pnpm run --no-bail now exits with a non-zero exit code when any of the executed scripts fail, while still running every matched script to completion. This makes the exit-code behavior of --no-bail consistent between recursive and non-recursive runs (recursive runs already failed at the end). Previously, a non-recursive pnpm run --no-bail always exited with code 0, even when a script failed #​8013.

  • 0474a9c: Added support for generating Node.js package maps at node_modules/.package-map.json during isolated and hoisted installs. Added the node-experimental-package-map setting to inject the generated map into pnpm-managed Node.js script environments, and the node-package-map-type setting to choose between standard and loose package maps.

  • dcededc: pnpm sbom now marks components reachable only through devDependencies with CycloneDX scope: "excluded" and the cdx:npm:package:development property. The excluded scope documents "component usage for test and other non-runtime purposes", which matches the semantics of a devDependency; the property is the CycloneDX npm-taxonomy marker emitted by @cyclonedx/cyclonedx-npm, so both modern (scope) and existing (property) consumers are covered. Components reachable at runtime (including installed optionalDependencies) omit scope and default to required.

  • 1495cb0: Added per-package SBOM generation with --out and --split flags. Use --out out/%s.cdx.json to write one SBOM per workspace package to individual files, or --split for NDJSON output to stdout. When --filter selects a single package, the SBOM root component now uses that package's metadata. Workspace inter-dependencies (workspace: protocol) and their transitive dependencies are included. Author, repository, and license fall back to the root manifest when the package doesn't define them.

  • 293921a: feat(view): support searching project manifest upward when package name is omitted

    When running pnpm view without a package name, the command now searches
    upward for the nearest project manifest (package.json, package.yaml, or package.json5) and uses its name field.
    If the manifest exists but lacks a name field, an error is thrown.

    This change also replaces the find-up dependency with empathic for
    improved performance and consistency across workspace tools.

Patch Changes
  • 29ab905: Fixed pnpm update overriding the version range policy of a named catalog whose name parses as a version (e.g. catalog:express4-21). The catalog: reference carries no pinning of its own, so the prefix from the catalog entry (such as ~) is now preserved instead of being widened to ^ #​10321.

  • bee4bf4: Security: validate config dependency names and versions from the env lockfile (pnpm-lock.yaml) before using them to build filesystem paths. A committed lockfile with a traversal-shaped configDependencies name (such as ../../PWNED) or version (such as ../../../PWNED) could previously cause pnpm install to create symlinks or write package files outside node_modules/.pnpm-config and the store. Names must now be valid npm package names and versions must be exact semver versions; the same validation is applied to optional subdependencies of config dependencies, and to the legacy workspace-manifest format before any lockfile is written. See GHSA-qrv3-253h-g69c.

  • 96bdd57: Fix link: workspace protocol switching to file: after pnpm rm is run from inside a workspace package whose target workspace dependency has its own dependencies, when injectWorkspacePackages: true is set. Follow-up to #​10575, which fixed the same symptom for workspace packages without dependencies.

  • 302a2f7: No longer warn about using both packageManager and devEngines.packageManager when the two fields pin the same package manager at the same version with the same integrity hash (e.g. both pnpm@11.5.1+sha512.…). Previously the hash was stripped from the legacy packageManager field but not from devEngines.packageManager, so even identical specifications looked like a mismatch #​12028.

    The warning still fires on any genuine divergence, and several cases now state the specific reason instead of a single generic message: a different package manager, a different version, or contradictory integrity hashes for the same version.

  • 3f0fb21: Fixed the progress line showing leftover characters from external processes that write to the terminal between progress updates (e.g. an SSH passphrase prompt would leave a fragment like added 0sa':). The interactive reporter now redraws each frame in place, erasing to the end of the display before reprinting, so any such remnants are cleared #​12350.

  • 564619f: Fixed pnpm approve-builds reporting "no packages awaiting approval" when a build-script dependency whose approval was revoked (e.g. after git stash drops the allowBuilds from pnpm-workspace.yaml) is re-added. The revoked packages are now correctly recorded in .modules.yaml so approve-builds can find them. #​12221

  • 3d1fd20: Skip the redundant "target bin directory already contains an exe called node" warning on Windows when the existing node.exe already matches the target (same hard link or identical content) pnpm/pnpm#12203.

  • 1b02b47: Fix macOS Gatekeeper blocking native binaries (.node, .dylib, .so) by removing the com.apple.quarantine extended attribute after importing them from the store.

    When pnpm imports files from its content-addressable store into node_modules, macOS preserves extended attributes, including com.apple.quarantine. If this xattr is present on a store blob (e.g. it was first written under a Gatekeeper-enabled app such as a Git client), it propagates to node_modules, and Gatekeeper blocks the native binary from loading even though pnpm already verified the file's integrity against the lockfile.

    After importing a package, pnpm now strips com.apple.quarantine from its native binaries, matching Homebrew's behaviour of dropping quarantine from verified downloads. The cleanup is macOS-only, runs in a single batched xattr call per package, is restricted to native binaries (other files are untouched), and is non-fatal (it logs a warning on unexpected errors).

    Fixes #​11056

  • 61969fb: Fix pnpm install with optimisticRepeatInstall incorrectly reporting Already up to date when pnpm-lock.yaml changed but project manifests did not. This affected workflows such as checking out or restoring only the lockfile #​12100.

    Also fixes checkDepsStatus to use the correct lockfile path when useGitBranchLockfile is enabled, so the optimistic fast-path and lockfile modification detection work with pnpm-lock.<branch>.yaml files instead of always stat'ing pnpm-lock.yaml. Merge-conflict detection now reads the resolved lockfile name as well, and with mergeGitBranchLockfiles enabled every pnpm-lock.*.yaml is scanned for modifications and conflicts. The git branch is now resolved by reading .git/HEAD directly (no process spawn) and uses the workspace directory rather than process.cwd().

  • 5c12968: Fix recursive updates of transitive dependencies when the update command mixes transitive dependency patterns with direct dependency selectors. For example, pnpm up -r "@&#8203;babel/core" uuid now updates matching transitive @babel/core dependencies even when uuid is a direct dependency selector #​12103.

  • 9d79ba1: Register the pnpm update --no-save flag in the CLI help and option parser.

  • 0474a9c: Fixed pnpm import for Yarn v2 lockfiles when js-yaml v4 is installed.

  • 9e0c375: Fixed pnpm install repeatedly prompting to remove and reinstall node_modules in a workspace package when enableGlobalVirtualStore is enabled. The post-install build step recorded a per-project node_modules/.pnpm virtual store directory in node_modules/.modules.yaml, overwriting the global <storeDir>/links value the install step had written. The next install then detected a virtual-store mismatch (ERR_PNPM_UNEXPECTED_VIRTUAL_STORE). The build step now derives the same global virtual store directory as the install step #​12307.

  • 223d060: Document the --cpu, --os and --libc flags in the output of pnpm install --help. These flags were already supported but were only documented on the website #​12359.

  • e85aea2: Avoid reading README.md from disk when publishing if the publish manifest already provides a readme field. The README is now only read lazily, inside createExportableManifest, when it is actually needed.

  • 3188ae7: Fixed pnpm peers check to accept loose peer dependency ranges such as >=3.16.0 || >=4.0.0- when the installed peer version satisfies the range #​12149.

  • 531f2a3: Fixed pnpm update rewriting a workspace: dependency that points at a local path (e.g. workspace:../packages/foo/dist) into a normalized link: or version-range specifier. Such specifiers are now preserved verbatim when the workspace protocol is preserved #​3902.

  • fe66535: Fixed a lockfile non-convergence bug where an incremental install kept a duplicate transitive dependency that a fresh install would not produce. When a package is reused from the lockfile, its child edges are taken verbatim and bypass the preferred-versions walk, so a transitive dependency could stay pinned to an older version even after a direct dependency resolved to a higher version that satisfies the same range. The resolver now refreshes such a stale pin to the higher direct-dependency version during resolution — so the older version is never resolved or fetched, and the incremental result converges to the fresh one.

  • 6d35338: pnpm install detects changes inside local file dependencies again. The optimistic repeat-install fast path only tracks manifest and lockfile modification times, so edits inside a local dependency's directory (or a repacked local tarball) were reported as "Already up to date". Projects with local file dependencies (file: and bare local path or tarball specifiers, declared directly or through pnpm.overrides) now always run a full install, which refetches those dependencies, matching pnpm v10 behavior #​11795.

  • 4ca9247: Preserve the existing Node.js runtime version prefix when resolving node@runtime:<range> to a concrete version.

  • 30c7590: Create shorter CAFS temporary package directories to leave room for lifecycle scripts that create IPC socket paths under TMPDIR.

  • 13815ad: Reporter output (warnings, progress) for pnpm store and pnpm config subcommands now goes to stderr instead of stdout. This fixes scripts that capture their stdout (e.g. PNPM_STORE=$(pnpm store path), pnpm config list --json | jq) from getting warnings mixed into the result.

  • 1c05876: Avoid relinking unchanged child dependencies and remove stale child links during warm installs.

  • 817f99d: Fixed lockfile churn where a package's transitivePeerDependencies could be dropped (and shift between packages) when the package participates in a dependency cycle. A cycle re-entry resolves against truncated children, so it must not be cached as "pure"; otherwise sibling occurrences of the same package short-circuit and lose transitive peers depending on traversal order #​5108.

  • eba03e0: Fix pnpm install reporting "Already up to date" after a catalog entry in pnpm-workspace.yaml was reverted to a previous version. After an update modified a catalog, the workspace state cache stored the pre-update catalog versions, so reverting the entry back to its original version was not detected as an outdated state #​12418.

  • 3b54d79: pnpm update now keeps lockfile overrides that resolve through a catalog in sync with the catalog. Previously, when an override referenced a catalog (e.g. overrides: { foo: 'catalog:' }) and pnpm update bumped that catalog entry, the lockfile's catalogs advanced while the resolved overrides kept the old version. The resulting lockfile was internally inconsistent, so a later pnpm install --frozen-lockfile failed with ERR_PNPM_LOCKFILE_CONFIG_MISMATCH.

  • 9d0a300: Fixed pnpm version --recursive so it honors the workspace selection. In recursive mode the version bump now applies to the packages resolved from the workspace filter (selectedProjectsGraph), matching the behavior of pnpm publish --recursive, instead of always bumping every workspace package #​11348.

v11.7.0

Compare Source

Minor Changes
  • Added a new setting frozenStore (--frozen-store) that lets pnpm install run against a package store on a read-only filesystem (e.g. a Nix store, a read-only bind mount, an OCI layer). When enabled, pnpm opens the store's SQLite index.db through the immutable=1 URI — bypassing the WAL/-shm sidecar creation that otherwise fails on a read-only directory — and suppresses every store-write path (the index.db writer and the project-registry write). Pair it with --offline --frozen-lockfile against a fully-populated store. Under the global virtual store, package directories live inside the store, so if the store is missing the build output of a package whose lifecycle scripts are approved (or that has a patch), pnpm fails up front with ERR_PNPM_FROZEN_STORE_NEEDS_BUILD rather than crashing mid-build on a read-only write — seed the store with those builds first. Incompatible with --force and with a configured pnpr server, since both write into the store; the side-effects cache is likewise not written under frozenStore. If the store is missing its content directory, the install fails fast with ERR_PNPM_FROZEN_STORE_INCOMPLETE rather than attempting to initialize it. The read-only immutable=1 open requires Node.js >=22.15.0, >=23.11.0, or >=24.0.0; on older runtimes --frozen-store fails with a clear ERR_PNPM_FROZEN_STORE_UNSUPPORTED_NODE error. Bin-linking also tolerates a read-only store: under the global virtual store a package's bin source lives inside the store, so the chmod that makes it executable would be refused — with EPERM/EACCES, or with EROFS on a genuinely read-only filesystem. That chmod is redundant when the seed already ships its bins executable with a normalized shebang, so it is now skipped in that case, while a non-executable bin (or one still carrying a Windows CRLF shebang) on a read-only store still errors.

  • When pacquet (the Rust port of pnpm) is declared in configDependencies, pnpm now delegates dependency resolution to it too — not just materialization — provided the installed pacquet is new enough to support full resolving installs (>= 0.11.7).

    Previously pacquet only ran in frozen-install mode: pnpm always resolved the dependency graph itself (writing pnpm-lock.yaml) and handed pacquet a finished lockfile to fetch / import / link. With pacquet >= 0.11.7, a non-frozen pnpm install (default isolated nodeLinker, plain install) is delegated to pacquet end-to-end in a single pass — pacquet resolves the manifests, writes the lockfile, and materializes node_modules. pnpm detects the capability from the installed pacquet's version; older pacquet releases keep the resolve-then-materialize split, and add / update / remove still resolve in pnpm (it has to mutate the manifests first). This remains an opt-in preview of the Rust install engine #​11723.

  • Added a new opt-in --batch flag to pnpm publish --recursive that sends all selected packages to the registry in a single PUT /-/pnpm/v1/publish request instead of one request per package. The target registry has to implement the batch publish endpoint (pnpr does); registries that don't are reported with a clear ERR_PNPM_BATCH_PUBLISH_UNSUPPORTED error. The batch is processed all-or-nothing by pnpr: if any package in the batch fails validation, none of the packages are published.

Patch Changes
  • Reject path-traversal and reserved dependency aliases (such as ../../../escape, .bin, .pnpm, or node_modules) that come from a lockfile rather than a freshly resolved manifest. A crafted lockfile alias could otherwise be joined directly under a hoisted node_modules directory, letting package files be written outside the intended install root or overwrite pnpm-owned layout.

    The fix adds two layers:

    • The nodeLinker: hoisted graph builder now validates each alias at the directory sink (safeJoinModulesDir), matching the validation pnpm already performs when resolving aliases from manifests.
    • The lockfile verification gate (verifyLockfileResolutions) now runs an always-on, policy-independent check that rejects any importer or snapshot dependency alias that is not a valid package name, failing the install early — before any fetch or filesystem work — for every node linker at once.
  • Made shared package child resolution deterministic when the same package is reached through multiple contexts. pnpm now chooses the shallowest occurrence, then importer order, then parent path, instead of letting request timing decide the child context and missing-peer report pnpm/pnpm#12358.

  • Fix garbled summary line after submitting pnpm update -i and pnpm audit --fix -i. The interactive checkbox prompt previously printed every selected choice's full table row (label, current/target versions, workspace, URL) joined by commas, producing a wall of text after pressing Enter. The summary now lists only the selected package names (or vulnerability keys) by setting an explicit short per choice; the in-progress selection UI is unchanged.

  • Prevent pnpm patch-remove from removing files outside the configured patches directory.

  • Fixed pnpm publish ignoring strictSsl: false when publishing to registries with self-signed certificates. The strictSSL option is now forwarded to libnpmpublish / npm-registry-fetch so that strict-ssl=false in .npmrc or strictSsl: false in pnpm-workspace.yaml is respected during publish, the same way it is for pnpm install pnpm/pnpm#12012.

  • Fixed Cannot destructure property 'manifest' of 'manifestsByPath[rootDir]' as it is undefined regression introduced in 11.6.0 when running pnpm add <pkg> outside a workspace on Windows. selectProjectByDir was keying the resulting ProjectsGraph by opts.dir instead of project.rootDir, so downstream manifestsByPath lookups missed when the two paths normalized differently (typically drive-letter casing). pnpm/pnpm#12379

  • Git dependencies that point to a subdirectory of a repository (repo#commit&path:/sub/dir) keep their path in the lockfile again. Since the integrity of git-hosted tarballs started being pinned in the lockfile, any install that actually downloaded the tarball rebuilt the lockfile resolution as { integrity, tarball, gitHosted } and dropped the path field, while installs served from the store kept it — so the field disappeared seemingly at random. Without path, later installs from that lockfile silently unpacked the repository root instead of the subdirectory #​12304.

  • Fixed nondeterministic lockfile output that made pnpm dedupe --check fail intermittently in CI. When a locked peer provider was pinned for a dependency that has no child dependencies of its own, the pinned provider leaked into the shared parent scope, so siblings resolved after it could pick up an optional peer they should not see. Which siblings were affected depended on resolution order, which varies with network timing.

  • Sped up pnpm install with a frozen lockfile by running lockfile verification (the policy revalidation gate added for minimumReleaseAge/trustPolicy and the tarball-URL anti-tamper check) concurrently with fetching and linking instead of blocking the whole install on it. Dependency lifecycle scripts are still held back until verification succeeds, so no script runs on an unverified lockfile: if verification fails the install aborts before any dependency build, and if linking finishes first the install waits for the verification verdict before completing.

  • User-defined npm_config_* environment variables are now preserved during lifecycle script execution. Previously, all npm_-prefixed env vars were stripped, which caused user-set variables like npm_config_platform_arch to be lost pnpm/pnpm#12399.

  • pnpm can now use different auth tokens for different package scopes, even when those scopes use the same registry URL.

    Previously, auth was selected only by registry URL. If @org-a and @org-b both used https://npm.pkg.github.com/, they had to share the same token. This caused problems for registries that issue tokens per organization or per scope.

    Configure a scope-specific token by adding the package scope after the registry URL in the auth key:

    @&#8203;org-a:registry=https://npm.pkg.github.com/
    @&#8203;org-b:registry=https://npm.pkg.github.com/
    
    //npm.pkg.github.com/:@&#8203;org-a:_authToken=${ORG_A_TOKEN}
    //npm.pkg.github.com/:@&#8203;org-b:_authToken=${ORG_B_TOKEN}
    
    //npm.pkg.github.com/:_authToken=${FALLBACK_TOKEN}

    pnpm login --registry=https://npm.pkg.github.com --scope=@&#8203;org-a writes the token to the same scope-specific auth key.

    When installing or publishing @org-a/*, pnpm uses ORG_A_TOKEN. For @org-b/*, pnpm uses ORG_B_TOKEN. Packages without a matching scope continue to use the registry-wide fallback token.

  • pnpm setup no longer prompts to approve build scripts for @pnpm/exe when installing the standalone executable. pnpm links the platform-specific binary itself, so the package's install scripts are skipped during the global self-install #​12377.

  • Close lockfile reads deterministically before rewriting lockfiles and keep pacquet's virtual store directory length aligned with pnpm on Windows.

  • A 304 Not Modified answer from the registry now renews the cached metadata file's mtime, so the minimumReleaseAge freshness shortcut keeps serving resolutions from the cache. Previously, once a cached packument grew older than minimumReleaseAge, every subsequent install re-validated it against the registry forever, because a 304 never rewrites the file.

  • Updated dependency ranges. Notably:

    • @pnpm/logger peer dependency range moved to ^1100.0.0.
    • msgpackr 1.11.8 → 2.0.4 (store index files remain byte-compatible in both directions).
    • open ^7.4.2 → ^11.0.0, memoize ^10 → ^11, cli-truncate ^5 → ^6, pidtree ^0.6 → ^1.
    • @yarnpkg/core 4.5.0 → 4.8.0, @rushstack/worker-pool 0.7.7 → 0.7.18, @cyclonedx/cyclonedx-library 10.0.0 → 10.1.0, @pnpm/config.nerf-dart ^1 → ^2, @pnpm/log.group 3.0.2 → 4.0.1, @pnpm/util.lex-comparator ^3 → ^4.
  • Updated @zkochan/cmd-shim to v9.0.6.

  • Fixed a Windows-only hang where a failed command could take 20–46 seconds to exit. On error, pnpm enumerates descendant processes (via pidtree) to terminate them, which on Windows shells out to wmic/PowerShell Get-CimInstance Win32_Process — a lookup that is extremely slow on some machines. The lookup is now bounded by a short timeout so it can no longer stall the process exit.

v11.6.0

Compare Source

Minor Changes
  • pnpm install completes without re-resolving when pnpm-lock.yaml was deleted but node_modules is intact: the up-to-date check now treats the current lockfile (node_modules/.pnpm/lock.yaml) — the record of what the previous install materialized — as the wanted lockfile, verifies the manifests still match it, restores pnpm-lock.yaml from it, and reports "Already up to date". Previously this scenario triggered a full resolution and a re-verification of every locked package against the registry.

  • 615c669: Added support for configuring URL-scoped registry settings through npm_config_//… and pnpm_config_//… environment variables, for example:

    npm_config_//registry.npmjs.org/:_authToken=<token>
    pnpm_config_//registry.npmjs.org/:_authToken=<token>
    

    This provides a file-free way to supply registry authentication. Because the registry a value applies to is encoded in the (trusted) environment variable name, it is host-scoped by construction and cannot be redirected to another registry by repository-controlled config. The environment value is treated as trusted config: it takes precedence over a project/workspace .npmrc but is still overridden by command-line options. When the same key is provided through both prefixes, pnpm_config_ wins.

  • Raised the default network concurrency from min(64, max(cpuCores * 3, 16)) to min(96, max(cpuCores * 3, 64)). Package downloads are I/O-bound, not CPU-bound, so deriving the floor from the core count left machines with few cores (for example 4-vCPU CI runners) downloading only 16 tarballs at a time and unable to saturate a low-latency registry. The networkConcurrency setting still overrides the default.

Patch Changes
  • Improved the warning printed when a project .npmrc uses an environment variable in a registry/proxy URL or in registry credentials. The message now explains why the setting was ignored and how to migrate it to a trusted source — for example by moving the line to the user-level ~/.npmrc or running pnpm config set "<key>" <value> — with a link to https://pnpm.io/npmrc. The pnpm config set example is only suggested when the key has no ${...} placeholder, so the snippet is always safe to copy-paste.
  • Print a "Lockfile passes supply-chain policies (verified 2h ago)" message when lockfile verification is skipped because a cached verdict for the same lockfile content and policy is reused. Previously the cached short-circuit was completely silent, which made it look like the policy gate never ran #​12324.
  • Platform-specific optional dependencies are now skipped even when their os/cpu/libc fields are missing from the registry metadata or the lockfile. Some

Note

PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about these updates again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

Package Changes Through 5a77ad6

There are 2 changes which include create-tauri-app with patch, create-tauri-app-js with patch

Planned Package Versions

The following package releases are the planned based on the context of changes in this pull request.

package current next
create-tauri-app 4.7.0 4.7.1
create-tauri-app-js 4.7.0 4.7.1

Add another change file through the GitHub UI by following this link.


Read about change files or the docs at github.com/jbolda/covector

@renovate renovate Bot force-pushed the renovate/pnpm-11.x branch 4 times, most recently from e1f75fb to d6b3d96 Compare May 14, 2026 13:02
@renovate renovate Bot force-pushed the renovate/pnpm-11.x branch 3 times, most recently from 31e57cb to 54298c6 Compare May 24, 2026 13:14
@renovate renovate Bot force-pushed the renovate/pnpm-11.x branch 3 times, most recently from 2d64f43 to 2f76270 Compare June 2, 2026 11:52
@renovate renovate Bot force-pushed the renovate/pnpm-11.x branch 2 times, most recently from fdacd69 to fd6e3bb Compare June 10, 2026 15:04
@renovate renovate Bot force-pushed the renovate/pnpm-11.x branch from fd6e3bb to 5a77ad6 Compare June 12, 2026 03:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants