Pular para o conteúdo principal

pnpm 11.25

· 7 min para ler
Zoltan Kochan
Lead maintainer of pnpm

pnpm 11.25 replaces topological batches with a task scheduler, adds configurable workspace task dependencies and per-task concurrency, and makes interrupted recursive runs resumable from the work that actually passed. It also introduces registry revisions, signed build artifacts shared through pnpr, batch approval for staged packages, automatic pruning of stale audit exceptions, and a pnpm init pin that follows the latest released pnpm.

Minor Changes

Workspace task orchestration

pnpm -r run now schedules individual project/script tasks as soon as their dependencies finish. Declare relationships under tasks in pnpm-workspace.yaml:

pnpm-workspace.yaml
tasks:
build:
dependsOn: ['^build']
concurrency: 2
test:
dependsOn: ['build']
lint: {}

^build means build in each workspace dependency; bare build means the task in the same project. A configured task with no dependsOn has no dependencies, while an unconfigured task retains the old default of depending on the same task in workspace dependencies. Missing scripts pass their edges through rather than cutting the graph.

Cycles now fail with ERR_PNPM_TASK_CYCLE unless ignoreWorkspaceCycles is set. --no-bail skips dependents of a failed task while independent work continues; the default --bail stops dispatch and cancels work already running. Use pnpm -r run --dry-run <script> to inspect the graph, and add --json for its machine-readable nodes and edges. See Workspace task orchestration.

The scheduler also replaces topological batches in workspace install, rebuild, pack, publish, stage, and lifecycle work: a project starts as soon as its dependencies finish instead of waiting for unrelated projects in the same group.

Resuming the work that passed

Recursive run and exec persist each successfully completed task. On a matching retry, --resume-from uses that record and skips exactly the work that passed, wherever it appears in the graph. The record is accepted only for the same selected projects, command, arguments, scripts, and execution-affecting settings.

Without a compatible record, pnpm falls back to the graph: it treats the named task's transitive dependencies as completed, while still running the named task, its dependents, and unrelated work.

Signed build artifacts shared through pnpr

The sideEffectsCache can now restore a dependency's build output across machines from pnpr. The repository declares which organization and packages are eligible; signing keys and all other publisher trust material are accepted only from the global config or the environment:

pnpm-workspace.yaml
pnprServer: https://packages.example.com
allowBuilds:
native-addon: true
sideEffectsCache:
remote:
org: acme
packages: [native-addon]

Artifacts are P-256 signed and bound to the package, source integrity, build input, and platform. Linux/glibc, macOS, and Windows are supported on x64 and arm64. A restored artifact is persisted in the shared store with its signed origin and reverified under the current keys, policy, source, and platform before later reuse; a bad variant is quarantined for that server. A cache miss or any verification, network, compatibility, or blob failure falls back to the ordinary local build.

The experimental protocol now gives every candidate and signed payload a discriminated subject: dependency builds carry package and source-integrity identity, while the protocol's workspace-task subject carries project and task identity. This changes request bodies and signed envelopes, so the pnpm client and pnpr server must be on matching releases.

The new object form also unites the local cache controls:

pnpm-workspace.yaml
sideEffectsCache:
read: true
write: true

It supports read-only and write-only caches. The older boolean sideEffectsCache, sideEffectsCacheReadonly, remoteSideEffectsCache, and organization spellings continue to work. See Shared side-effects cache.

Registry revisions

A revision-aware registry can replace the artifact of an already-published version without rewriting the canonical name@version URL. pnpm records a selected replacement beside its integrity:

pnpm-lock.yaml
packages:
lodash@4.17.21:
resolution:
integrity: sha512-<replacement-digest>
revision: 1

No revision means revision 0, the immutable original, so lockfiles that use no replacements retain their existing shape. A dependency or override can select one explicitly with <version>+rN; +r0 pins the original. Run pnpm update --patches to refresh the selected artifacts without changing any package version or declared range. The refresh may run through the configured pnpr server. See Registry revisions.

Batch approval for staged publishing

pnpm stage approve accepts several stage ids, or opens an interactive picker when none are passed. One OTP approves the whole batch until the registry stops accepting it. Workspace packages are approved in dependency order, and a dependent is skipped when its workspace dependency could not be approved.

pnpm init follows latest

pnpm init now looks up the pnpm version behind the latest tag and pins it when it is newer than the running pnpm. An offline, unreachable, slow, policy-rejected, or older result falls back to the running version and never fails or delays the scaffold indefinitely (#7490).

Pruning stale audit exceptions

Set audit.ignorePrune: true to make pnpm audit --fix remove ignored GHSA entries that no longer occur in the audit report. An exception for an advisory still present in the report is kept.

A project cannot choose the login scope

A scope key in a project's pnpm-workspace.yaml is now ignored with a warning. pnpm login turns its scope into a machine-wide registry route, so a repository must not be able to choose it. Pass --scope, set PNPM_CONFIG_SCOPE, or set scope in the global config instead (#13557).

Patch Changes

Registry and update correctness

  • A registry or registries declaration now wins over a route inferred from global _auth; the pnpm_config__auth environment setting deliberately remains higher priority for CI-controlled routing.
  • pnpm update preserves a dependency's declared range or catalog: reference when an override also matches it, including when the override repeats the range verbatim (#12115, #14224).
  • pnpm update -g no longer downgrades a package whose installed version is newer than latest, and it leaves pnpm itself to pnpm self-update (#14270).
  • --production is accepted again as the alias of --prod on install, fetch, prune, update, list, why, and sbom (#14147).

Installation and build fixes

  • An install reached through a symlinked node_modules no longer rewrites the target checkout, and pnpm add --lockfile-only no longer links dependencies (#14286).
  • Incremental installs validate unused patches correctly, and deploy --prod works when an omitted dev dependency is also an optional peer (#13692, #14302).
  • Reusing a prepared git dependency from the shared store now enforces allowBuilds, and approval suggestions use its canonical git resolution id.
  • Hoisted copies of a built package no longer replace a destination directory and delete dependencies nested under its node_modules (#12880).
  • The remote cache avoids downloading blobs already present in the store, uses environment names under PNPM_SIDE_EFFECTS_CACHE_REMOTE_* (the old names remain aliases), and pnpr resolution now receives patch hashes and package extensions.

Workspace and package-manager fixes

  • Workspace project sorting is now linear-time, fixing long stalls on deep workspaces with thousands of projects (#14149, #14151).
  • Recursive-run cleanup terminates sibling process trees correctly on Windows.
  • A satisfied devEngines.packageManager range is now recorded in the lockfile's packageManagerDependencies with the running version as its shared resolution.
  • Automatic pnpm switching no longer forces descendant pnpm processes to use the parent's version (#14309).
  • Update guidance now points to pnpm self-update only when PNPM_HOME manages pnpm; Corepack and other package-manager installs point to the standalone installer.

For the complete list, see the v11.25.0 release notes.