Minor Changes
-
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
remoteSideEffectsCachesetting. A workspace names the eligibleorganizationandpackages; everything describing the act of signing —publish,keyId,builderId,trustedKeys,privateKeyand the provenance fields — is refused inpnpm-workspace.yamland 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.ignorePrunesetting. When set totrue,pnpm audit --fixremoves ignored GHSA entries that no longer appear in the audit report. -
Generalized the experimental shared-artifact protocol so candidates and signed payloads identify a discriminated subject. Dependency side effects use package and source-integrity subjects, while workspace tasks use project and task subjects.
This changes shared-artifact request bodies and signed payloads. A pnpr server and its clients have to be on matching versions.
-
pnpm initnow pins the latest pnpm version, instead of the version of pnpm that ran the command. A project scaffolded by an outdated pnpm therefore no longer inherits that staleness through its owndevEngines.packageManager/packageManagerpin #7490.The version is read from the
latesttag on the package-manager registries. When that lookup cannot answer — no network, an unreachable or slow registry,offline, or alatestthat theminimumReleaseAge/trustPolicysettings reject —pnpm initpins the running version as before, and never fails or hangs on the lookup. Alatestthat is older than the running pnpm is never pinned either. -
A
scopeset in a project'spnpm-workspace.yamlis now ignored, with a warning naming where to set it instead.pnpm loginrecords the scope as a@scope:registryroute in the machine-globalauth.ini, which outranks~/.npmrcin every project — so a repository-committed file could redirect a scope such as@acmefor all of a user's other projects after one routine login. Use--scope, thePNPM_CONFIG_SCOPEenvironment 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).
-
Persist completed recursive tasks so
--resume-fromskips exactly the work that passed during a matching interrupted or failedpnpm -r run/pnpm -r execinvocation. When no compatible state exists, pnpm retains its graph-based resume behavior. -
Allowed
pnpm update --patchesto refresh registry revisions through a configured pnpr server while retaining locked package versions. -
Added explicit registry revision selection with
<version>+rNandpnpm update --patchesfor refreshing revision artifacts without changing package versions. Registry-backed lockfile policy checks recognize historical revisions, and pnpr now preserves safe revision histories from upstream registries. -
Workspace install, rebuild, pack, publish, stage, and lifecycle work now starts as soon as its dependencies finish instead of waiting for an unrelated topological group.
-
pnpm stage approvenow approves several staged packages at once. Run it without a stage id to pick from the staged versions interactively, or pass a list of stage ids. The whole batch is approved with a single one-time password, and pnpm asks for a new one only once the registry stops accepting it. Inside a workspace, the selected packages are approved in dependency order, and a package whose workspace dependency could not be approved is skipped instead of being published against a dependency that never reached the registry. -
Added per-task concurrency limits to workspace task orchestration. Set
tasks.<name>.concurrencyinpnpm-workspace.yamlto limit how many instances of that task may run across workspace projects at once:tasks: build: concurrency: 2
-
Added support for registry replacement tarballs using standard integrity values, explicit revision fields, registry routing from the
registriessetting, non-redirecting integrity-addressed URLs, canonical safe-integer revision numbers, and pnpr proxying for immutable upstream revision artifacts. -
sideEffectsCachenow declares the whole of how a package's build output is reused — whether one is restored, whether one is saved, and the remote tier that shares it between machines:sideEffectsCache: read: true write: true remote: org: acme packages: ['native-addon']
sideEffectsCache: true,sideEffectsCacheReadonly,remoteSideEffectsCache, and itsorganizationfield all keep working. Where a field is set under both spellings the one above wins; where it is set under only one, it is kept.Two behaviors change, both bringing this CLI in line with what the Rust one already did:
sideEffectsCacheReadonly: truenow blocks writing to the cache, and setting it alongsidesideEffectsCache: falsegives a read-only view rather than switching the cache off entirely. A cache can also be declared write-only now, to populate one the run does not read. -
Workspace task orchestration (pnpm/rfcs#23).
pnpm -r runandpnpm -r execnow schedule per task instead of in topological chunks: a task starts as soon as the tasks it depends on have finished, so a project no longer waits for unrelated projects that happen to share its chunk.A new
taskssection inpnpm-workspace.yamldeclares what a task depends on, using the^convention:tasks: build: dependsOn: ['^build'] test: dependsOn: ['build'] lint: {}
^namemeans the named task in each of the project's workspace dependencies; a barenamemeans the task in the same project; an entry with nodependsOndeclares an empty dependency list. A task with no entry behaves asdependsOn: ['^<its own name>'], which is exactly what the previous chunked ordering implied — an unconfigured workspace gets the scheduler improvement and nothing else changes meaning. A project without the script is reported skipped and passes its edges through to its own dependencies, so a scriptless package does not sever a chain.Also part of this change:
- A dependency cycle among the tasks of a run is now an error naming the participating tasks (
ERR_PNPM_TASK_CYCLE) instead of silently running in an arbitrary order. SettingignoreWorkspaceCycles: truedowngrades the error to a warning: the cycle's tasks run in an arbitrary order relative to each other. --resume-fromnow skips exactly the transitive dependencies of the anchor package; work unrelated to the anchor still runs.- Under
--no-bail, tasks whose dependencies failed are reported as skipped, not failed, and do not add to the exit code. - With
--bail(the default), the first failure still ends the run at once and nothing new is dispatched — including scripts already queued behind the concurrency limit. pnpm -r run --dry-run <script>prints the task graph that would execute without running anything (including skipping theverifyDepsBeforeRuncheck);--jsonemits the tasks and their resolved dependency edges.- Output is inherited rather than piped only when at most one script can ever be in flight (
--workspace-concurrency=1, or the graph forces the scripts to run one after another).
- A dependency cycle among the tasks of a run is now an error naming the participating tasks (
Patch Changes
-
An
_authentry in the global config file no longer decides which registry packages come from when something else says. Aregistryorregistriesdeclared inpnpm-workspace.yamlor the global config now wins over the route inferred from a stored credential, which still applies where nothing else declares one. Thepnpm_config__authenvironment variable is unchanged: it stays the way to point a CI runner at a mandated proxy, and still overrides what a repository declares. -
Prevent installs through a symlinked
node_modulesdirectory from rewriting the target checkout pnpm/pnpm#14286. -
Treat empty scripts selected by a regular expression as missing before running dependent tasks.
-
The options type of the
fetchcommand now declaresallowBuilds, a setting its handler already forwarded to the installer. Type-level only — whatpnpm fetchdoes is unchanged. -
Filter hidden scripts matched by a regular expression during recursive runs when a visible script also matches.
-
Fixed automatically switched pnpm versions forcing all descendant pnpm processes to use the same version pnpm/pnpm#14309.
-
Fixed
ERR_PNPM_UNUSED_PATCHvalidation during incremental installs pnpm/pnpm#13692. -
Fixed
pnpm deploy --prodfailing when an excluded dev dependency was also declared as an optional peer dependency pnpm/pnpm#14302. -
pnpm update -gno longer downgrades a global package.--latestresolves thelatestdist-tag, which can point at an older release than the one installed — afterpnpm add -g <pkg>@next, for instance #14270.pnpm update -galso no longer changes the pnpm version. pnpm's own global install belongs topnpm self-update#14270. -
Copying a built package to its other hoisted locations no longer replaces the destination directory. With
nodeLinker: hoisted, that replacement deleted the dependencies nested inside the destination'snode_modules, and made concurrent copies of the same build chunk fail withERR_PNPM_ENOENT: no such file or directory, rename '.../node_modules/_tmp_...'#12880. -
pnpm updateno longer replaces the specifier a project declares for a dependency that is also listed inoverrides. Acatalog:reference stays acatalog:reference, and a declared range stays as written, instead of being rewritten to the version the override resolved to #12115. -
pnpm updateno longer moves the range a project declares for a dependency thatoverridesalso lists, even when the override repeats that range verbatim. Previously the updatedpackage.jsondisagreed with the lockfile, so the nextpnpm install --frozen-lockfilefailed with a specifier mismatch #14224. -
Make
pnpm add --lockfile-onlyskip dependency linking pnpm/pnpm#14286. -
--productionis accepted again as an alias of--prodoninstall,fetch,prune,update,list,why, andsbom, and the install thatverifyDepsBeforeRunreproduces is now spelled with--prod.pnpm runno longer aborts with "unexpected argument '--production' found" after a production-only install #14147. -
The progress output no longer overwrites the lines above it once it grows taller than the terminal window #14270.
-
Restoring a dependency's build from the remote side-effects cache no longer downloads files the store already holds.
-
Forward
patchedDependencieshashes andpackageExtensionsto pnpr so server-side resolution preserves patches and package extensions in the lockfile and installed packages. -
Published the workspace task graph and scheduler as
@pnpm/workspace.task-schedulerso other workspace commands can use the same dependency-aware scheduling as recursive run and exec. -
The environment variables for the remote side-effects cache are named for the setting they configure:
PNPM_SIDE_EFFECTS_CACHE_REMOTE_KEY_ID,..._BUILDER_ID,..._IMAGE_DIGEST,..._ARCHITECTURE_BASELINE,..._PRIVATE_KEY,..._BUILD_ENV,..._TRUSTED_KEYSand..._PUBLISH. ThePNPM_REMOTE_SIDE_EFFECTS_CACHE_*names keep working, and the new one wins when both are set. -
A
devEngines.packageManagerrange pin on pnpm is now recorded inpnpm-lock.yaml'spackageManagerDependencieswhen the running pnpm already satisfies it, using the running version and keeping the range as the recorded specifier. Previously only an exact pin — or a range resolved on the way through a version switch — reached the lockfile, so a range pin written by hand (or by any tool other thanpnpm add/pnpm self-update) left the project without the shared resolution the pin exists to provide. -
Fixed recursive
runcleanup on Windows when a lifecycle script fails while another script's process tree is still running. -
The update notification now suggests
pnpm self-updatewhenPNPM_HOMEmanages the pnpm in use, and the standalone install script otherwise — under Corepack, or when another package manager installed pnpm.pnpm self-updateunder Corepack names the standalone install script too. -
Enforce
allowBuildswhen a prepared git dependency is reused from the shared store, and use the lockfile's canonical git resolution ID in approval suggestions. -
Topologically sorting workspace projects now runs in linear time, fixing installs and lockfile updates that stalled for seconds on workspaces with thousands of projects forming deep dependency chains #14149, #14151.
Platinum Sponsors
|
|
|
|
Gold Sponsors
|
|
|
|
|
|
|
|
|
|
|
|