releases.shpreview
Home/Collections/JavaScript Runtimes & Tooling

JavaScript Runtimes & Tooling

Runtimes, package managers, bundlers, and test runners powering JS and TS projects.

WedJun 3, 20261 release
Denov2.8.2
MonJun 1, 20263 releases
FriMay 29, 20261 release

pnpm 11.5

pnpm 11.5 adds a hoistingLimits setting for controlling how far dependencies hoist in nodeLinker: hoisted installs, replaces the interactive prompt library to fix scrolling in long choice lists, recognizes staged publishes in the trust scale, and ships several install and dist-tag fixes.

Minor Changes

New hoistingLimits setting

A new hoistingLimits setting controls how far dependencies are hoisted when using nodeLinker: hoisted. It mirrors yarn's nmHoistingLimits and accepts:

  • none - hoist as far as possible (the default).
  • workspaces - hoist only as far as each workspace package.
  • dependencies - hoist only up to each workspace package's direct dependencies.

Originally proposed in #6468, closing #6457.

New interactive prompt library

pnpm replaced enquirer with @inquirer/prompts for all interactive prompts. This fixes the update -i scrolling overflow bug where long choice lists were clipped in the terminal (#6643). The new library uses visual-line-aware pagination, so scrolling now works correctly when many packages are available.

Affected commands include pnpm update -i (and --latest), pnpm audit --fix -i, pnpm approve-builds, pnpm patch, pnpm patch-remove, pnpm publish, pnpm login, and pnpm run / pnpm exec (with verifyDepsBeforeRun=prompt).

Vim-style j / k keys still work for up/down navigation in all interactive prompts.

Staged publishes recognized in the trust scale

Staged publishes are now recognized in the trust scale. When a package version's registry metadata carries an approver field, it is treated as the strongest trust evidence (ranked above trusted publishers and provenance attestations), since staged publishes require 2FA publish approvals. This prevents false-positive trust downgrade errors when moving from a staged publish to a lower trust level (#11887).

Patch Changes

  • Fix pnpm hanging during peer resolution when an aliased install pulls in transitive packages with mutual peer cycles at different depths in the dependency tree (for example, pnpm i nuxt@npm:nuxt-nightly@5x) (#11999).
  • Fix pnpm dist-tag add and pnpm dist-tag rm against npmjs.org failing without --otp. pnpm now surfaces the OTP challenge through the existing browser-based 2FA flow (the same one used by pnpm publish), so the browser opens, the user authenticates, and the dist-tag is set on retry. --otp=<code> continues to work via the classic flow.
  • Fix minimumReleaseAgeExclude handling in npm resolution fast paths so excluded packages do not get pinned to stale versions.
  • Fix the integrity field being dropped from the lockfile entry of a remote (non-registry) https-tarball dependency when an unrelated package is installed afterwards. The missing integrity could otherwise make subsequent --frozen-lockfile installs fail with ERR_PNPM_MISSING_TARBALL_INTEGRITY (#12001).
  • Skip dependency re-resolution when pnpm-lock.yaml is missing but node_modules/.pnpm/lock.yaml exists and still satisfies the manifest. pnpm install now reuses the materialized snapshot to regenerate pnpm-lock.yaml instead of walking the registry to rebuild it from scratch (#11993). --frozen-lockfile still refuses to proceed when pnpm-lock.yaml is absent.

"undefined"!=typeof _bsa&&_bsa&&_bsa.init("custom","CWYI4K7E","placement:pnpmio",{target:"#bsa-custom-01",template:` <a href="##link##" class="native-banner" style="background: ##backgroundColor##" rel="sponsored noopener" target="\_blank" title="##company## — ##tagline##"> <img class="native-img" width="125" src="##logo##" /> <div class="native-main"> <div class="native-details" style=" color: ##textColor##; border-left: solid 1px ##textColor##; "> <span class="native-desc">##description##</span> </div> <span class="native-cta" style=" color: ##ctaTextColor##; background-color: ##ctaBackgroundColor##; ">##callToAction##</span> </div> </a> `})

Read post
ThuMay 28, 20261 release
Turborepov2.9.16
WedMay 27, 20262 releases
Denov2.8.1

pnpm 11.4

pnpm 11.4 closes a cluster of supply-chain holes around lockfile integrity, credential scoping, git resolutions, patch files, and dependency aliases, makes tarball-integrity mismatches a hard install failure by default (with a narrowly-scoped --update-checksums opt-in), and changes pnpm runtime set to write to devEngines.runtime instead of engines.runtime by default.

Minor Changes

Tarball-integrity mismatches are now a hard failure

Previously, pnpm install (non-frozen) would log ERR_PNPM_TARBALL_INTEGRITY when a downloaded tarball's hash didn't match the lockfile, silently re-resolve from the registry, and overwrite the locked integrity. A compromised registry, proxy, or republished version could therefore substitute attacker-controlled content on a clean machine even though the project shipped a committed lockfile.

pnpm install now exits with ERR_PNPM_TARBALL_INTEGRITY and a hint pointing at the new opt-in flag.

The only opt-in is pnpm install --update-checksums — narrowly scoped to refreshing the locked integrity values from what the registry currently serves. It mirrors yarn's flag of the same name. A warning still prints when the bypass takes effect so the operation is auditable.

--force and pnpm update deliberately do not bypass the integrity check. They are routine refresh operations; silently overwriting a locked integrity in those flows would erase the protection a committed lockfile is supposed to provide. --frozen-lockfile behavior is unchanged. --fix-lockfile keeps its documented purpose (filling in missing lockfile entries) and is also not a bypass.

pnpm runtime set writes to devEngines.runtime by default

pnpm runtime set <name> <version> now saves the runtime to devEngines.runtime by default instead of engines.runtime. Pass --save-prod (or -P) to save it to engines.runtime instead. See #11948.

Patch Changes

Security: unscoped credentials no longer leak across registries

An unscoped _authToken (or _auth, or username + _password, or tokenHelper) defined in one source — ~/.npmrc, ~/.config/pnpm/auth.ini, a workspace .npmrc, CLI flags, etc. — would be sent as an Authorization header to whichever registry a different (potentially untrusted) source named. The same exposure extended to client TLS credentials (cert, key).

pnpm now rewrites each unscoped per-registry setting (_authToken, _auth, username, _password, tokenHelper, cert, key) to its URL-scoped form at load time, using the registry= value declared in the same source (or the npmjs default registry if the source declares none). A later layer overriding registry= therefore cannot pull an unscoped credential along, because it is already pinned to the URL its author intended. ca / cafile are intentionally not rescoped — they're trust anchors, not credentials, and corporate MITM-proxy setups rely on them applying globally.

Every rescope emits a deprecation warning telling the user where the setting was pinned and how to write it directly. npm has rejected unscoped credentials outright since npm@9, and pnpm intends to remove support in a future major release. To target a specific registry, write the setting URL-scoped:

.npmrc

<span class="token-line" style="color:#393A34"><span class="token key attr-name" style="color:#00a4db">//registry.example.com/:_authToken</span><span class="token punctuation" style="color:#393A34">=</span><span class="token value attr-value" style="color:#e3116c">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key attr-name" style="color:#00a4db">//registry.example.com/:cert</span><span class="token punctuation" style="color:#393A34">=</span><span class="token value attr-value" style="color:#e3116c">...</span><br></span>
Security: lockfile entries without integrity are rejected

Previously, the worker that extracts a downloaded tarball skipped hash verification when no integrity was supplied and minted a fresh one from the unverified bytes. An attacker who could both alter the lockfile (e.g. via a pull request that strips integrity:) and serve modified content at the referenced tarball URL could install a tampered package without any error — including under --frozen-lockfile.

pnpm now fails closed at lockfile-read time with ERR_PNPM_MISSING_TARBALL_INTEGRITY. Git-hosted tarballs (gitHosted: true or a URL on codeload.github.com / bitbucket.org / gitlab.com) and file: tarballs are exempt — the commit SHA in a git-host URL and the user-controlled local path already anchor the bytes.

Security: git resolutions reject non-SHA commit fields

Git resolutions whose commit field is not a 40-character hexadecimal SHA are rejected before git is invoked. A malicious lockfile could otherwise smuggle a value such as --upload-pack=<command> through git fetch / git checkout, which on SSH or local-file transports executes the supplied command.

Security: patch files writing outside the package directory are rejected

Patch files whose diff --git headers reference paths outside the patched package directory are now rejected. Previously a malicious .patch file added via a pull request could write, delete, or rename arbitrary files reachable by the user running pnpm install.

Security: dependency aliases with path-traversal segments are rejected

Dependency aliases that contain path-traversal segments (such as @x/../../../../../.git/hooks) are rejected when read from a package manifest or symlinked into node_modules. A malicious registry package could otherwise use a transitive dependency key to make pnpm install create symlinks at attacker-chosen paths outside the intended node_modules directory.

Trusted-publisher metadata now requires provenance

Trusted publisher metadata is only treated as the strongest trust evidence when provenance is also present.

Other fixes
  • Fix pnpm deploy crashing with ENOENT: ... lstat '<deployDir>/node_modules' when configDependencies declares pacquet (pacquet or @pnpm/pacquet). The deploy directory never installs config dependencies, so the install engine they designate isn't on disk to invoke; the nested install now skips them.
  • Limit concurrent project manifest reads while listing large workspaces to avoid EMFILE errors.
  • Validate devEngines.runtime and engines.runtime version ranges for node, deno, and bun when onFail is set to error or warn. Previously these settings only had an effect with onFail: 'download' — the error and warn modes silently did nothing #11818. Violations now throw ERR_PNPM_BAD_RUNTIME_VERSION.
  • Improve the log message that pnpm prints after auto-adding entries to minimumReleaseAgeExclude when minimumReleaseAge is set without minimumReleaseAgeStrict. The message previously referred to the internal "loose mode" terminology, which wasn't searchable in the docs; it now tells the user to set minimumReleaseAgeStrict to true if they want these updates gated behind a prompt instead #11747.

"undefined"!=typeof _bsa&&_bsa&&_bsa.init("custom","CWYI4K7E","placement:pnpmio",{target:"#bsa-custom-01",template:` <a href="##link##" class="native-banner" style="background: ##backgroundColor##" rel="sponsored noopener" target="\_blank" title="##company## — ##tagline##"> <img class="native-img" width="125" src="##logo##" /> <div class="native-main"> <div class="native-details" style=" color: ##textColor##; border-left: solid 1px ##textColor##; "> <span class="native-desc">##description##</span> </div> <span class="native-cta" style=" color: ##ctaTextColor##; background-color: ##ctaBackgroundColor##; ">##callToAction##</span> </div> </a> `})

Read post
TueMay 26, 20261 release
Turborepov2.9.15
SunMay 24, 20261 release

pnpm 11.3

pnpm 11.3 adds support for npm's staged publishing (pnpm stage), the new trustLockfile setting for skipping the supply-chain verification pass on already-trusted lockfiles, and native implementations of pnpm pkg, pnpm repo, and pnpm set-script. It also adds a --skip-manifest-obfuscation flag for pack / publish and cuts the memory footprint of minimumReleaseAge / trustPolicy verification on large workspaces.

Minor Changes

pnpm stage

A new pnpm stage command brings npm's staged publishing workflow to pnpm. Staged publishing lets you publish a version that's hidden from npm install until you explicitly approve it — useful for verifying release artifacts, smoke-testing CI, or coordinating multi-package releases.

The available subcommands are:

<span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">pnpm</span><span class="token plain"> stage publish    </span><span class="token comment" style="color:#999988;font-style:italic"># publish a version into staging</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">pnpm</span><span class="token plain"> stage list       </span><span class="token comment" style="color:#999988;font-style:italic"># list staged versions</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">pnpm</span><span class="token plain"> stage view       </span><span class="token comment" style="color:#999988;font-style:italic"># view a staged version</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">pnpm</span><span class="token plain"> stage approve    </span><span class="token comment" style="color:#999988;font-style:italic"># promote a staged version to the registry</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">pnpm</span><span class="token plain"> stage reject     </span><span class="token comment" style="color:#999988;font-style:italic"># discard a staged version</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">pnpm</span><span class="token plain"> stage download   </span><span class="token comment" style="color:#999988;font-style:italic"># download a staged tarball</span><br></span>
trustLockfile

A new trustLockfile setting controls whether pnpm install re-applies the minimumReleaseAge / trustPolicy: 'no-downgrade' checks to every entry in the loaded lockfile. When true, the install treats the lockfile as already-trusted and skips the verification pass — useful for closed-source projects where every commit comes from a trusted author. The default is false, so verification stays on by default.

Set it in pnpm-workspace.yaml:

pnpm-workspace.yaml

<span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">trustLockfile</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#36acaa">true</span><br></span>

This release also cuts the memory footprint of the verification pass itself: the per-(registry, name) trust-meta cache previously retained the full packument — dependency graphs, scripts, README, and per-version manifests — for the entire install. On large workspaces (~4k lockfile entries with minimumReleaseAge + trustPolicy: no-downgrade enabled) this could OOM CI runners with a 2 GB heap cap. The cache now stores only the fields the trust check actually reads (time, per-version _npmUser.trustedPublisher, dist.attestations.provenance); the abbreviated-metadata cache is similarly projected to just the package-level modified field and the set of currently-listed version names. Fixes #11860.

Native pnpm pkg, pnpm repo, and pnpm set-script

Three more commands that previously delegated to (or were missing without) npm are now implemented natively, following the npm command conventions:

  • pnpm pkg — get / set / delete fields in package.json.
  • pnpm repo — open the repository URL of a package in the browser.
  • pnpm set-script (alias ss) — add or update an entry in the scripts field of the project manifest. Supports package.json, package.json5, and package.yaml formats.
--skip-manifest-obfuscation for pack and publish

A new --skip-manifest-obfuscation flag for pnpm pack and pnpm publish keeps the original packageManager field and publish lifecycle scripts in the packed/published manifest instead of stripping them. The pnpm-specific pnpm field continues to be omitted.

Patch Changes

  • Fixed pnpm dlx failing with ERR_PNPM_NO_IMPORTER_MANIFEST_FOUND when the installed package's CAS slot is missing its package.json. Observed in the wild for pnpm dlx node@runtime:<version> when the GVS slot was populated without the synthesized manifest runtime archives need. dlx now falls back to the scopeless package name when the slot's manifest is unreadable — for single-bin packages (the dlx common case, including every runtime: spec) this matches what manifest.bin would have named.
  • Fixed non-determinism in pnpm dedupe and pnpm install when a dependency graph contains packages with transitive peer dependencies on each other (e.g. @aws-sdk/client-sts and @aws-sdk/client-sso-oidc) and auto-install-peers is enabled. The lockfile no longer flips between two equally-valid forms across consecutive runs. The root cause was that resolveDependencies pushed onto its pkgAddresses / postponedResolutionsQueue arrays from inside Promise.all-spawned callbacks, so completion-order timing leaked into the array order and downstream cyclic-peer suffix assignment. Fixes #8155.
  • Fixed a regression where pnpm add <github-shorthand> (and any other wanted-dependency whose alias can't be parsed from the user-supplied spec, e.g. tarball URLs or pnpm/test-git-fetch#sha) was silently dropped from the manifest update and from pendingBuilds.
  • Fixed pnpm add --config leaving orphan entries in pnpm-lock.env.yaml (the optional subdependencies of the previously resolved version of the updated config dependency).

"undefined"!=typeof _bsa&&_bsa&&_bsa.init("custom","CWYI4K7E","placement:pnpmio",{target:"#bsa-custom-01",template:` <a href="##link##" class="native-banner" style="background: ##backgroundColor##" rel="sponsored noopener" target="\_blank" title="##company## — ##tagline##"> <img class="native-img" width="125" src="##logo##" /> <div class="native-main"> <div class="native-details" style=" color: ##textColor##; border-left: solid 1px ##textColor##; "> <span class="native-desc">##description##</span> </div> <span class="native-cta" style=" color: ##ctaTextColor##; background-color: ##ctaBackgroundColor##; ">##callToAction##</span> </div> </a> `})

Read post
FriMay 22, 20262 releases

Deno 2.8

`import defer`, six new subcommands (`deno transpile`, `deno pack`, `deno bump-version`, `deno ci`, `deno why`, `deno audit fix`), network debugging in Chrome DevTools, framework-aware `deno compile`, and 3.66x faster cold npm installs.

Read post
Denov2.8.0
ThuMay 21, 20261 release
WedMay 20, 20262 releases
vitestv4.1.7

pnpm 11.2

pnpm 11.2 ships an experimental opt-in into pacquet (the Rust port of pnpm) as the install backend, expands config dependencies to install one level of optionalDependencies (so the esbuild/swc platform-binary pattern works for config deps too), wires up the long-documented pnpm login --scope flag, and surfaces runtime entries (Node.js, Deno, Bun) in pnpm outdated and pnpm update --interactive.

Minor Changes

Experimental: pacquet as the install backend

Adding @pnpm/pacquet (the Rust port of pnpm) to configDependencies in pnpm-workspace.yaml now delegates the materialization phase of pnpm install to the pacquet binary. pnpm still owns dependency resolution; pacquet only fetches and imports from the freshly-written lockfile. This is an opt-in preview of the Rust install engine — see #11723.

To configure pacquet in a project, run:

<span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">pnpm</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">add</span><span class="token plain"> @pnpm/pacquet </span><span class="token parameter variable" style="color:#36acaa">--config</span><br></span>

You'll see changes in pnpm-workspace.yaml and pnpm-lock.yaml that should be committed. If you experience any issues with pacquet, please let us know in the GitHub issue you create.

optionalDependencies for config dependencies

Config dependencies now resolve and install one level of optionalDependencies declared by the config dependency, with os / cpu / libc platform filtering applied at install time. This unlocks the esbuild/swc-style pattern where a package ships platform-specific binaries via optionalDependencies — a config dependency can now do the same and have the matching binary symlinked next to it in the global virtual store, so require('pkg-platform-arch') from inside the config dependency resolves correctly.

The env lockfile records all platform variants regardless of host platform, so it remains portable across machines. Each entry in a config dependency's optionalDependencies must declare an exact version — ranges and tags are rejected to keep installs reproducible.

pnpm login --scope

The long-documented pnpm login --scope <scope> flag is now implemented. The scope is normalized (a leading @ is added if missing; blank values are ignored) and an @<scope>:registry=<registry> mapping is written to the pnpm auth file alongside the auth token. Subsequent installs of @<scope>/* packages then route to the chosen registry. Previously the documented flag errored with Unknown option: 'scope'. See #11716.

Runtimes in outdated and update --interactive

pnpm outdated and pnpm update --interactive now report Node.js, Deno, and Bun runtimes installed as project dependencies (runtime: specifiers). Previously these were silently skipped.

Patch Changes

  • Fixed cafile=<relative-path> in .npmrc being read from the wrong directory when pnpm is invoked from a different cwd (e.g. pnpm --dir <project> install from a CI wrapper or monorepo script). The path is now resolved against the directory of the .npmrc that declared it, not process.cwd(). Before this fix, the install proceeded without the configured CA and the user only saw TLS errors against a private registry with no log line tying back to the wrongly resolved path #11624.
  • Fixed config.registry getting a trailing slash appended when registry is set in .npmrc and no registries.default is provided by pnpm-workspace.yaml.
  • Fixed global add/update to handle minimumReleaseAge policy violations instead of surfacing an internal resolver guardrail error.
  • Fixed two crashes with injectWorkspacePackages: true when the lockfile has been pruned (e.g. by turbo prune --docker): a Cannot use 'in' operator to search for 'directory' in undefined from peer-dependency-variant injected snapshots whose base packages: entry had been dropped, and an ERR_PNPM_ENOENT on node_modules/.bin/<tool> after prepare / postinstall re-imported each injected workspace package.
  • Fixed pnpm login and pnpm logout ignoring registries.default from pnpm-workspace.yaml #10099.
  • Fixed the minimumReleaseAge (publishedBy) maturity shortcut to be inclusive at the cutoff. Previously, abbreviated metadata whose modified field equalled the cutoff fell off the fast path and triggered a full-metadata re-fetch (or a MISSING_TIME error when full metadata wasn't permitted).
  • Honor publishConfig.access when publishing packages.

11.2.1

  • Mark optional subdependency snapshots of config dependencies with optional: true in the env lockfile, matching how optional dependencies are recorded elsewhere in pnpm-lock.yaml. Previously, snapshots for the platform-specific subdeps pulled in via a config dep's optionalDependencies were written as empty objects.
  • Fixed pickRegistryForPackage returning the wrong registry for an unscoped npm: alias under a scoped local name. A manifest entry like "@private/foo": "npm:lodash@^1" was routing the lodash fetch through registries["@private"], even though lodash is unscoped.
  • Don't print Installing config dependencies... when config dependencies are already installed and nothing needs to be fetched, re-linked, or removed.

11.2.2

  • When the install engine is delegated to pacquet via configDependencies, the user's CLI flags passed to pnpm install (e.g. --no-runtime, --prod, --dev, --no-optional, --node-linker, --cpu / --os / --libc, --offline, --prefer-offline) are now forwarded to pacquet's install subcommand verbatim. Previously pacquet was invoked with a fixed argument list, so flags like --no-runtime were silently dropped. Flag forwarding is gated on the command being install / i; add, update, and dedupe still don't forward (their flag surface doesn't line up with pacquet's install).
  • Fixed pnpm up (and pnpm add / pnpm remove) failing with pacquet_package_manager::outdated_lockfile when pacquet is declared in configDependencies. pnpm now passes --ignore-manifest-check to pacquet so its --frozen-lockfile check doesn't fire against the (pre-mutation) package.json pnpm hasn't written yet #11797.

"undefined"!=typeof _bsa&&_bsa&&_bsa.init("custom","CWYI4K7E","placement:pnpmio",{target:"#bsa-custom-01",template:` <a href="##link##" class="native-banner" style="background: ##backgroundColor##" rel="sponsored noopener" target="\_blank" title="##company## — ##tagline##"> <img class="native-img" width="125" src="##logo##" /> <div class="native-main"> <div class="native-details" style=" color: ##textColor##; border-left: solid 1px ##textColor##; "> <span class="native-desc">##description##</span> </div> <span class="native-cta" style=" color: ##ctaTextColor##; background-color: ##ctaBackgroundColor##; ">##callToAction##</span> </div> </a> `})

Read post
ThuMay 14, 20261 release
Turborepov2.9.14
WedMay 13, 20261 release
Bunbun-v1.3.14
MonMay 11, 20262 releases
vitestv4.1.6

pnpm 11.1

pnpm 11.1 adds a few new commands — pnpm audit signatures, pnpm bugs, and pnpm owner — alongside support for installing from arbitrary named registries (including a built-in alias for the GitHub Packages npm registry), the ability to skip runtime installation in CI, and several fixes.

Minor Changes

pnpm audit signatures

A new pnpm audit signatures subcommand verifies ECDSA registry signatures for installed packages against keys published at /-/npm/v1/keys #7909. Scoped registries are respected; registries that don't publish signing keys are skipped.

pnpm audit signatures
Named registries (and a built-in gh: alias)

You can now install packages from the GitHub Packages npm registry via a built-in gh: prefix, and — more broadly — from arbitrary named registries in the style of vlt's named-registry aliases:

pnpm add gh:@acme/private

Authentication is picked up from existing per-URL .npmrc entries (e.g. //npm.pkg.github.com/:_authToken=...), so no separate auth mechanism is required.

Additional aliases — or an override for the built-in gh alias, for GitHub Enterprise Server — can be configured under namedRegistries in pnpm-workspace.yaml:

pnpm-workspace.yaml

namedRegistries:
  gh: https://npm.pkg.github.example.com/
  work: https://npm.work.example.com/

With this, work:@corp/lib@^2.0.0 resolves against https://npm.work.example.com/. See #8941.

--sbom-spec-version

pnpm sbom now accepts a --sbom-spec-version flag to choose the CycloneDX specification version (1.5, 1.6, or 1.7 — default 1.7). The flag is only valid with --sbom-format cyclonedx. See #11389.

--no-runtime for CI matrices

A new --no-runtime flag (config: runtime=false) skips installing runtime entries (e.g. Node.js downloaded via devEngines.runtime) without modifying the lockfile. The lockfile keeps the runtime entry so frozen-lockfile validation still passes; only the runtime fetch and .bin linking are skipped. This is useful in CI matrices where the runtime is provisioned externally (e.g. via pnpm runtime -g set node ) before pnpm install runs.

pnpm bugs

The new pnpm bugs command opens a package's bug tracker URL in the browser. With no arguments, it reads the current project's package.json; with one or more package names, it fetches each package's metadata from the registry and opens its bug tracker. It falls back to /issues when the bugs field is missing. See #11279.

pnpm owner

The new pnpm owner command manages package owners on the registry:

pnpm owner ls package>
pnpm owner add package> user>
pnpm owner rm package> user>

Patch Changes

pnpm view now prints "published X ago by Y" alongside the rest of its output, mirroring npm view. This is useful when comparing against minimumReleaseAge. For example, pnpm view pnpm now shows published 17 hours ago by GitHub Actions.

pnpm publish now honors the configured HTTP/HTTPS proxy (including the https_proxy / http_proxy / no_proxy environment variables) when polling the registry's doneUrl during the web-based authentication flow. Previously the poll bypassed the proxy, causing the registry to respond 403 from a different source IP and the login to never complete #11561.

pnpm add -g now installs each space-separated package into its own isolated directory by default. To bundle multiple packages into the same isolated install (so they share dependencies and are removed together), pass them as a comma-separated list. For example:

pnpm add -g foo bar installs foo and bar as two independent globals — removing one does not affect the other.

  • pnpm add -g foo,bar qar bundles foo and bar into a single isolated install while qar is installed on its own.

Related: #11587.

pnpm runtime set no longer fails in the root of a multi-package workspace with the ADDING_TO_ROOT error. Installing the workspace root is a valid target for a runtime, so the command now bypasses that safety check.

Fixed pnpm --version hanging for the lifetime of the worker pool after the version was printed. The CLI entry now runs finishWorkers() from its own finally, so every exit path tears the pool down.

"undefined"!=typeof _bsa&&_bsa&&_bsa.init("custom","CWYI4K7E","placement:pnpmio",{target:"#bsa-custom-01",template:`

##description##

##callToAction##

`})

Read post
SatMay 9, 20261 release
Turborepov2.9.12