Release Notes
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 aERR_PNPM_MISSING_TARBALL_INTEGRITYlockfile verification violation (the install fails closed) rather than being silently re-fetched. - 6c35a43: Added
--exclude-peerstopnpm sbom. Withauto-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 matchespnpm list --exclude-peers; note the SBOM flag prunes a peer's exclusive subtree, which is stricter thanpnpm list(which only hides leaf peers).
Patch Changes
25a829e:
pnpm audit --fixnow writes a single combinedminimumReleaseAgeExcludeentry per package (e.g.[email protected] || 0.21.1) instead of one entry per version, matching the format documented for the setting. Existing per-version entries inpnpm-workspace.yamlare merged into the combined form rather than left as duplicates. Installs that auto-collect immature versions intominimumReleaseAgeExcludenow 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 throughstyled-jsx— from a package's peer-dependency suffix across otherwise identical installs, churning the lockfile and causing intermittentpnpm dedupe --checkfailures 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 dlxwhere a failed install could surface a spuriousEBUSY: resource busy or lockederror. 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 dlxcache path so deep dependency trees no longer overflow Windows'MAX_PATH, which could make a dependency's lifecycle script fail withspawn cmd.exe ENOENT.05b95ab: Fixed
pnpmhanging (and crashing with an unhandled promise rejection) when a non-retryable network error such asSELF_SIGNED_CERT_IN_CHAINoccurs 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 auditperformance 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
enableGlobalVirtualStoreis toggled on for a project that was previously installed without it, stale hoisted symlinks undernode_modules/.pnpm/node_modulesare now replaced instead of being left pointing at the old per-project virtual store location #9739.6545793: Fixed
pnpm install --ignore-workspaceoverwriting theallowBuildsmap inpnpm-workspace.yaml. The ignored builds of a package with a build script were auto-populated intoallowBuildseven though--ignore-workspacewas passed, clobbering committedtrue/falsevalues with theset this to true or falseplaceholder #12469.fbdc0eb: Fixed
minimumReleaseAgeExcludeandtrustPolicyExcludeso 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[[email protected], [email protected]]could still flag[email protected]as violatingminimumReleaseAge, while[[email protected] || 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 patchdropping 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
/-/pnprnamespace:POST /v1/resolveis nowPOST /-/pnpr/v0/resolveandPOST /v1/verify-lockfileis nowPOST /-/pnpr/v0/verify-lockfile. The capability handshake atGET /-/pnpradvertises protocol version0to 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.runtimeorengines.runtimeentry that was materialized from it. Blank runtime selectors are normalized tolatest.17e7f2c:
pnpm sbomnow emits a CycloneDXissue-trackerexternal reference for components (and the root) whosepackage.jsondeclares abugsURL. Email-onlybugsentries 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 vendorsgetNpmTarballUrl(previously the externalget-npm-tarball-urlpackage) and addsisCanonicalRegistryTarballUrl, the predicate the lockfile writer uses to decide whether a tarball URL is derivable from name+version+registry (and can therefore be omitted frompnpm-lock.yaml).Exposing
isCanonicalRegistryTarballUrllets a custom resolver (pnpmfileresolvers) fronting a proxy that serves tarballs on a non-canonical path (e.g. an ephemerallocalhost:<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
%2Fas well as%2f(percent-encoding is case-insensitive), and protocol-insensitive comparison strips only a leadinghttp(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/401on a private registry, or a network error) asERR_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 asERR_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.
Platinum Sponsors
|
|
|
|
Gold Sponsors
|
|
|
|
|
|
|
|
|
|
|