# pnpm v12.0.0-rc.7 — pnpm 12 RC 7 - Product: pnpm (https://whatsnew.fyi/product/pnpm) - Vendor: pnpm - Date: 2026-08-18 - Version: v12.0.0-rc.7 - Original notes: https://github.com/pnpm/pnpm/releases/tag/v12.0.0-rc.7 - Permalink: https://whatsnew.fyi/product/pnpm/releases/v12.0.0-rc.7 - Labels: Pre-release What's New is an index, not a publisher: every entry below links to the vendor's own release notes, which are the authoritative source. Entries are labelled where they are hand-curated sample data, pre-releases, or drawn from a secondary source such as a developer blog. Reuse: the summaries, labels and curation here are © What's New. Quote freely with attribution and a link back; wholesale republication of the corpus is not permitted — terms: https://whatsnew.fyi/terms. The vendors' own release notes remain their publishers'. --- - **changed** — node_modules/.modules.yaml no longer records the registries an install resolved from, and the recorded copy is dropped from the file on the first install that rewrites it - **changed** — pnpm list, pnpm why, and single-project installs now use the configured registries instead of the recorded copy from node_modules/.modules.yaml - **changed** — When enableGlobalVirtualStore is on, every process pnpm spawns for the project now receives a NODE_PATH pointing at the project's hoisted node_modules, plus a NODE_OPTIONS --import flag that registers a resolve hook restoring NODE_PATH lookups for ESM imports - **added** — A registry can now declare that its abbreviated metadata carries the time field via the supportsTimeField configuration option - **changed** — resolutionMode: time-based now reads the full metadata document only from the registries that declare they need it, instead of falling back to full metadata everywhere - **changed** — A pnpr resolve request now carries the client's registries keyed by URL with scopes routed to each and each one's serverType, in place of the prefix map - **changed** — A pnpr server now routes scoped dependencies from the registry that scope is routed to, which it previously could not - **changed** — A registry a pnpr request only declares is no longer refused up front for being off the server's allowlist - **changed** — A resolve request now carries the client's resolutionMode, so an install delegated to a pnpr server picks versions the way the client would - **changed** — The registries setting now declares a registry once, keyed by its URL, with everything about that registry in the entry including how it lays out tarball URLs, the scopes routed to it, and the bare-specifier prefix it answers to - **added** — The serverType configuration option tells pnpm how a registry lays out its tarball URLs, supporting undeclared (default), npm, and artifactory types ##### Minor Changes - `node_modules/.modules.yaml` no longer records the registries an install resolved from, and the recorded copy is dropped from the file on the first install that rewrites it. It dated from the lockfile format that spelled a dependency's path relative to its registry, where reading an installed tree meant knowing the registries it was installed with. Dependency paths have not carried a registry for several major versions, and the recorded copy outlived its use: `pnpm list`, `pnpm why`, and single-project installs preferred it over the project's own configuration, so a project whose registry had changed since its last install was still read through the old one. They now use the configured registries, like every other command already did. - When `enableGlobalVirtualStore` is on, every process pnpm spawns for the project (`pnpm run`, `pnpm exec`, lifecycle scripts) now receives a `NODE_PATH` pointing at the project's hoisted `node_modules`, plus a `NODE_OPTIONS` `--import` flag that registers a resolve hook restoring `NODE_PATH` lookups for ESM imports. Dependencies that import undeclared ("phantom") packages keep resolving under the global virtual store — for both CommonJS and ESM — without installing the `@pnpm/plugin-esm-node-path` config dependency [pnpm/pnpm#9618](https://github.com/pnpm/pnpm/issues/9618). Tools run by `pnpm dlx` resolve such dependencies too: the JS CLI passes them the same environment, while the Rust CLI's dlx cache is self-contained, so its layout already exposes them. - A registry can now declare that its abbreviated metadata carries the `time` field, so `resolutionMode: time-based` reads the full metadata document only from the registries that need it: ```yaml resolutionMode: time-based registries: https://npm.internal.example/: supportsTimeField: true ``` `registry.npmjs.org` omits `time` from abbreviated metadata, so a time-based resolution has to fall back to the much larger full document. That fallback used to be all-or-nothing: `registrySupportsTimeField` answered for every registry at once, so a project resolving from both the public registry and a Verdaccio instance either paid for full metadata everywhere or claimed a `time` field npmjs does not serve. The answer is now per registry, and `registrySupportsTimeField` remains the answer for every registry that does not declare one. The declaration is also sent to a pnpr server, which applies it to the resolution it runs on the client's behalf. - A pnpr resolve request now carries the client's registries the way the `registries` setting declares them — keyed by URL, with the scopes routed to each, the bare-specifier prefix each answers to, and each one's `serverType` — in place of the prefix map it used to send. The server routes them through the same inversion the config reader runs, so a pnpr-served install resolves a scoped dependency from the registry that scope is routed to, which it previously could not: only the default registry and the prefix-addressed ones reached the server. A declared `serverType` reaches it too, so the tarball URLs pnpr omits from the lockfile match the ones the client reconstructs. Built-in scope routes the project has not pointed elsewhere are not declared, so a pnpr server's allowlist is not asked about `npm.jsr.io` on requests that resolve no JSR package. A registry a request only declares is no longer refused up front for being off the server's allowlist — a client describes its whole configuration, including scopes a given resolve never reaches, so a stray `@scope:registry` in a developer's `~/.npmrc` no longer fails every install against a pnpr server that does not serve it. The boundary moves to the fetch itself: an origin the resolve does reach is refused before the request leaves the server, with the same message. This changes the resolve and verify-lockfile request bodies. A pnpr server and its clients have to be _[Truncated at 4000 characters — full notes: https://github.com/pnpm/pnpm/releases/tag/v12.0.0-rc.7]_