Skip to main content

pnpm 12.1

· 6 min read
Zoltan Kochan
Lead maintainer of pnpm

pnpm 12.1 brings the new workspace task scheduler to the Rust CLI, persists successful recursive tasks for precise retries, expands shared build artifacts to macOS and Windows, and moves login credentials into pnpm's structured global configuration. pnpr 0.1.0-alpha.9, released with it, makes the artifact tier independent and horizontally scalable through S3-compatible storage.

Minor Changes

Workspace task orchestration

pnpm -r run and pnpm -r exec now dispatch a project as soon as its dependencies finish instead of waiting for an unrelated topological group. Recursive scripts can declare cross-task relationships and per-task concurrency under tasks:

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

The scheduler detects task cycles, passes dependencies through projects that do not define a script, skips failed dependents under --no-bail, cancels in-flight work under the default --bail, and supports --dry-run --json graph output. Workspace install, rebuild, pack, publish, stage, and lifecycle work uses the same start-as-soon-as-ready scheduling. See Workspace task orchestration.

Successful recursive run and exec tasks are persisted. A matching --resume-from retry skips exactly what passed; an incompatible or missing record falls back to omitting the named task's transitive dependencies from the graph.

Login writes structured global configuration

pnpm login and pnpm adduser now write the granted token to the global config.yaml under _auth. With --scope, they also add the scope to that registry's global registries declaration, so the credential and the route that reaches it are recorded together.

pnpm logout removes credentials from config.yaml and still cleans an auth.ini written by an older pnpm. Existing auth.ini tokens remain readable. A scope in project pnpm-workspace.yaml is ignored with a warning; use --scope, PNPM_CONFIG_SCOPE, or the global config because a login route is machine-wide (#13557).

Shared build artifacts on Linux, macOS, and Windows

sideEffectsCache now provides one object for local read/write behavior and the remote pnpr tier:

pnpm-workspace.yaml
sideEffectsCache:
read: true
write: true
remote:
org: acme
packages: [native-addon]

Read-only and write-only caches are supported. The legacy boolean, sideEffectsCacheReadonly, remoteSideEffectsCache, and organization spellings keep working and are merged with the new shape.

Remote artifacts now support Linux/glibc, macOS, and Windows on x64 and arm64. Verified artifacts are persisted in the shared store with their signed origin, reverified against the current trust, policy, platform, source, and stored files before reuse, and quarantined per pnpr server when invalid. The protocol now uses discriminated subjects, so dependency side effects and future workspace task artifacts cannot collide. The protocol changed; clients and pnpr servers must use matching releases. See Shared side-effects cache.

Patch Changes

Configuration and authentication

  • Explicit registry and registries settings now beat routes inferred from global _auth; environment _auth remains the CI-controlled override.
  • The command-line forms of package import, hoisting, global and virtual store paths, modules paths, child concurrency, lockfile, peer, side-effects cache, trust-policy, and optimistic-repeat-install settings are accepted again (#14281).
  • Basic _auth tolerates omitted or extra base64 padding and embedded whitespace, while malformed base64 and a missing username:password separator receive explicit errors (#14257).

Command correctness

  • pnpm clean and pnpm purge from a workspace subdirectory remove each project's own node_modules, and pnpm pm clean / pnpm pm purge force the built-in command even when a package script shadows it (#14239, #14226).
  • pnpm dlx <pkg>@catalog: resolves through the calling workspace's catalogs (#14294).
  • .mjs pnpmfiles and config-dependency hooks load on Windows again (#14301), and pnpm pack applies files to root changelog, history, and notice files.
  • pnpm update -g neither downgrades a package installed from a newer tag nor changes pnpm itself. pnpm update preserves catalog and range declarations matched by overrides (#14270, #12115, #14224).
  • When several installed versions expose the same binary, the highest version supplies the linked command (#14249).
  • pnpm view --json and its aliases print errors as JSON, and the OTP prompt no longer contains a duplicate colon.
  • pnpm add, update, and remove save the requested manifest change before reporting ERR_PNPM_IGNORED_BUILDS, since the dependency is already materialized at that point.

Install behavior and performance

  • An artifact-only pnpr tier is accepted, and pnpm install --fix-lockfile works through pnpr—including filtered installs—while preserving compatible locked versions (#14250).
  • Git-hosted patchedDependencies match in fresh and frozen installs (#14273); production deploys no longer fail over excluded optional peers (#14302).
  • Workspace project linking is concurrent, no-script installs skip unnecessary build work, and hoisted workspaces no longer rescan every project to find bins.
  • Lockfile resolution and warm restoration overlap the Node.js version probe, saving roughly 150–200 ms in the affected paths.
  • On macOS, the default isolated linker materializes each package once and uses one copy-on-write directory clone per virtual-store copy, fixing the many-core warm-install regression and reducing filesystem calls (#14231).
  • Bailing from recursive run or exec now stops in-flight process trees.

pnpr 0.1.0-alpha.9

The signed shared-artifact cache now uses its own top-level artifacts.enabled switch, independent of the registry and resolver surfaces. An artifact-only tier can therefore scale separately from compute-heavy resolution. With an s3: block, artifacts use the reserved .pnpr-artifacts/v0/ namespace in S3, R2, MinIO, or another compatible object store; conditional quota updates make the tier safe to share across replicas.

Publication slots are immutable across overlapping compatibility sets. A later universal, broader, or higher-floor artifact cannot replace the bytes a machine already receives; disjoint operating-system, architecture, and Node.js-major builds still coexist. Identical retries remain idempotent. After an ambiguous object-store write failure, pnpr waits for active publications to drain, reclaims blobs referenced by no envelope, and rebuilds quota without losing the fail-closed storage bounds.

The v0 protocol now binds every candidate and signed payload to a discriminated subject: package plus source integrity for dependency side effects, or project plus task for workspace tasks. It also recognizes fixLockfile resolve requests. These request and envelope changes require matching pnpr and pnpm versions.

For the complete client changes, see the v12.1.0 release notes. The server changes are in the pnpr 0.1.0-alpha.9 release notes.