Change8

v12.0.0-alpha.16

Breaking Changes
📦 pnpmView on GitHub →
2 breaking13 features🐛 15 fixes1 deprecations🔧 47 symbols

Summary

This release enhances pnpm's runtime installation parity across Node.js, Deno, and Bun, introduces native commands like `install-test` and `recursive`, and improves the robustness of installations and dependency management, including better handling of patched dependencies and optional packages.

⚠️ Breaking Changes

  • The `virtualStoreOnly` setting, when combined with `enableModulesDir: false`, now fails with `ERR_PNPM_CONFIG_CONFLICT_VIRTUAL_STORE_ONLY_WITH_NO_MODULES_DIR` unless `enableGlobalVirtualStore` is on. This is because the standard virtual store resides within `node_modules`.
  • `pnpm install` now fails with `ERR_PNPM_UNUSED_PATCH` when an entry in `patchedDependencies` does not match any installed package. To revert to the previous warning behavior, set `allowUnusedPatches: true` in `pnpm-workspace.yaml`.

Migration Steps

  1. If you are using `virtualStoreOnly` with `enableModulesDir: false`, ensure `enableGlobalVirtualStore` is enabled or adjust your configuration to avoid `ERR_PNPM_CONFIG_CONFLICT_VIRTUAL_STORE_ONLY_WITH_NO_MODULES_DIR`.
  2. If you encounter `ERR_PNPM_UNUSED_PATCH` errors, either update your `patchedDependencies` to match installed packages or set `allowUnusedPatches: true` in your `pnpm-workspace.yaml` to revert to a warning.
  3. If you previously relied on `pnpm add` to move dependencies between groups, be aware that it now moves them instead of creating duplicates.
  4. If you previously relied on `pnpm add <pkg>` without a `--save-*` flag to always save to `dependencies`, be aware that it now updates the dependency in its existing group.

✨ New Features

  • Completed pnpm runtime installation parity for Node.js, Deno, and Bun, including runtime failure policy, target architecture selection, and dependency runtime engines.
  • Implemented native `install-test` command.
  • Implemented native `recursive`, `multi`, and `m` commands in the Rust CLI.
  • Added the `virtualStoreOnly` setting for populating the virtual store without post-import linking.
  • Repeat installs now reconcile the existing `node_modules` more robustly, handling removed direct dependencies, unlinking hoisted aliases, detecting hand-deleted packages, and failing `pnpm add` / `pnpm remove` on layout drifts.
  • `pnpm install --ignore-scripts` now records skipped builds in `node_modules/.modules.yaml`'s `pendingBuilds`, and `pnpm rebuild --pending` can now run them.
  • `pnpm install` now detects `supportedArchitectures` changes and re-evaluates previously skipped platform-specific optional dependencies.
  • Conditional metadata requests now send `If-Modified-Since` as an HTTP-date, allowing registries to respond with `304 Not Modified`.
  • Fixed two global-virtual-store correctness gaps: failed builds now discard the hash directory, and side-effects-cache hits correctly materialize build output when the store slot has been re-imported.
  • `.modules.yaml` now records the `allowBuilds` setting used during the install.
  • Aligned large-download progress byte formatting with pnpm.
  • Changing `--os` / `--cpu` / `--libc` or `supportedArchitectures` between installs now re-evaluates previously skipped optional dependencies.
  • Removing a package from `allowBuilds` now fails the next `pnpm install` under `strictDepBuilds`.

🐛 Bug Fixes

  • Runtime failure overrides now preserve explicit runtime dependencies without matching engine entries.
  • `pnpm add` no longer drops other dependency groups from the install. Adding a package with `optionalDependencies` no longer leaves dangling optional-dependency symlinks in the virtual store, and a production `pnpm add` no longer removes `devDependencies` from `pnpm-lock.yaml` and `node_modules`.
  • `pnpm add` with `--save-dev`, `--save-optional`, or `--save-prod` now moves an already-declared dependency to the target group instead of leaving a duplicate entry.
  • `pnpm add <pkg>` without a `--save-*` flag now updates an already-declared dependency in its current group instead of always saving it into `dependencies`.
  • Avoided optimistic repeat-install shortcuts when a lockfile contains merge conflict markers.
  • `pnpm setup` now removes leftover v10-layout shims at the top of `PNPM_HOME`, preventing `pnpm self-update` from warning about a v10 installation layout after PATH migration.
  • A git-hosted dependency with no host archive now records the bare `git+<repo>#<commit>` reference in the lockfile's importer entry.
  • A private git-hosted dependency resolved over HTTPS with an embedded auth token is now recorded as a `type: git` resolution against the authenticated remote.
  • When a dependency's build script fails under `enableGlobalVirtualStore`, the global virtual store directory is now removed for scoped packages too.
  • A hoisted-linker install no longer fails with `ERR_PNPM_LOCKFILE_MISSING_DEPENDENCY` when an optional dependency's snapshot is absent.
  • Fixed patched dependencies being applied to only one copy of a package under `nodeLinker: hoisted`. Every copy is now patched.
  • `pnpm install` now announces `Lockfile is up to date, resolution step is skipped` whenever the headless installer runs.
  • `pnpm fetch` now prints `Importing packages to virtual store` on the up-to-date lockfile path.
  • Fixed a bug where a failed build under `enableGlobalVirtualStore` would leave a half-built directory behind.
  • Fixed a bug where a side-effects-cache hit would incorrectly assume the store slot still held the cached build, leading to skipped builds.

Affected Symbols

⚡ Deprecations

  • Deprecated packages are now reported during installation. Directly depended-on deprecated packages will show an immediate warning, while deprecated subdependencies will be summarized at the end of the installation. Versions matched by `pnpm.allowedDeprecatedVersions` will not trigger warnings.