chore(deps): update pnpm to v12.9.0
Metadata
Current evaluation
Merged Renovate PR updating pnpm from 12.6.0 to 12.9.0 in package.json and pnpm-lock.yaml.
Resolution: closed resolved
Reason: PR #127 was merged after approval and passing CI checks, applying the pnpm v12.9.0 dependency update.
Evaluated by: mr-cal-bot
No scores available.
Issue body
> ℹ️ **Note**
>
> This PR body was truncated due to platform limits.
This PR contains the following updates:
| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [pnpm](https://redirect.github.com/pnpm/pnpm/tree/main/pnpm) ([source](https://redirect.github.com/pnpm/pnpm/tree/HEAD/pnpm/npm/pnpm)) | [`12.6.0` → `12.9.0`](https://renovatebot.com/diffs/npm/pnpm/12.6.0/12.9.0) |  |  |
---
### Release Notes
<details>
<summary>pnpm/pnpm (pnpm)</summary>
### [`v12.9.0`](https://redirect.github.com/pnpm/pnpm/releases/tag/v12.9.0): pnpm 12.9
[Compare Source](https://redirect.github.com/pnpm/pnpm/compare/v12.8.2...v12.9.0)
This release runs pnpm in StackBlitz WebContainers, adds a per-registry `networkConcurrency` setting, and records every installed project in the store. It also carries a security fix for `pnpm login`.
##### Minor Changes
- pnpm now automatically uses WebAssembly in StackBlitz WebContainers, including when installation scripts are disabled. Native installations continue to use the native executable when installation scripts are enabled.
- A `registries` entry can now set `networkConcurrency`, the most requests pnpm keeps in flight to that registry's origin. Requests to other registries keep the overall limit. The setting may live in `pnpm-workspace.yaml` or the global `config.yaml`.
```yaml
registries:
https://npm.corp.example.com/:
scopes: ["@acme"]
networkConcurrency: 4
```
- `pnpm install` now records every project it installs in the store's `projects` directory, as a symlink to the project directory. A `--frozen-store` install without the global virtual store still records nothing. Only projects that used the global virtual store were recorded before [#​6929](https://redirect.github.com/pnpm/pnpm/issues/6929).
##### Patch Changes
- `pnpm login` no longer forwards credentials in its request body to another origin during redirects.
##### Installing packages
- Fixed `pnpm install` failing on Android with `ERR_PNPM_STORE_DIR_ACQUIRE_OPERATION_LOCK` [#​16508](https://redirect.github.com/pnpm/pnpm/issues/16508).
- `pnpm install --frozen-lockfile` again succeeds when a workspace project recorded in `pnpm-lock.yaml` has no directory, such as a project left out of a Docker build context. It still fails if the project's directory exists without a `package.json` [#​16453](https://redirect.github.com/pnpm/pnpm/issues/16453).
- `pnpm install --frozen-lockfile` no longer requires a `pnpm-lock.yaml` in a project that has no dependencies. It also succeeds when `pnpm-lock.yaml` records only the pinned pnpm version, as other commands write it when they run before the first install [#​16477](https://redirect.github.com/pnpm/pnpm/issues/16477).
- Fixed `pnpm install --frozen-lockfile` rejecting a fresh lockfile when an injected workspace dependency has an optional peer supplied by another workspace project [#​16428](https://redirect.github.com/pnpm/pnpm/issues/16428).
- With `nodeLinker: hoisted`, a filtered install now keeps the packages of the workspace projects an earlier install put in `node_modules`. This also covers the install that `pnpm --filter <selector> run` and `pnpm --filter <selector> exec` start before the command. Before, these installs removed every package that only the unselected projects needed [#​16483](https://redirect.github.com/pnpm/pnpm/issues/16483).
- `pnpm install` with `nodeLinker: hoisted` now refreshes directories supplied by custom fetchers when reinstalling. pnpm also keeps the symlinks inside those directories.
- With `enableGlobalVirtualStore` on, scripts can run entry points that a CommonJS require hook loads again, such as `ts-node index.ts`. They failed with `ERR_UNKNOWN_FILE_EXTENSION` on Node.js versions without built-in TypeScript support [#​16436](https://redirect.github.com/pnpm/pnpm/issues/16436).
- pnpm now keeps each project's current lockfile and hidden hoisted dependencies in its own `node_modules/.pnpm` when `virtualStoreDir` points at a shared global virtual store. `--virtual-store-dir` now sets the global virtual store's location too [pnpm/tasks#47](https://redirect.github.com/pnpm/tasks/issues/47).
- `pnpm clean` no longer deletes the project when `virtualStoreDir` or `globalVirtualStoreDir` is set to the project directory. It also leaves a directory outside the project alone when the setting reaches it through a symlink. It now removes a global virtual store that `globalVirtualStoreDir` places inside the project, as it does for `virtualStoreDir`.
##### Optional dependencies
- `pnpm install` no longer fails when a dependency of an optional dependency is missing from the registry. Like npm, pnpm now leaves out the nearest optional dependency above it, together with its subtree [#​16511](https://redirect.github.com/pnpm/pnpm/issues/16511).
- When an optional dependency fails to build, pnpm now removes its link from `node_modules`. A repeat `pnpm install` then reports "Already up to date" and no longer reruns the failing build [#​16468](https://redirect.github.com/pnpm/pnpm/issues/16468).
- `pnpm install` now prints a warning with the error when an optional dependency cannot be fetched and is skipped. The skipped package is no longer counted in the `Packages: +N` summary. The `pnpm:skipped-optional-dependency` log reports the skip with the `fetch_failure` reason [#​16514](https://redirect.github.com/pnpm/pnpm/issues/16514).
##### Resolving dependencies
- Fixed `pnpm install` changing an unchanged project's direct dependency to a sibling workspace's pinned version when its dependency tree contains a cycle [#​16417](https://redirect.github.com/pnpm/pnpm/issues/16417).
- With `autoDedupe` enabled, downgrading a dependency in one workspace project now moves the other projects to that version when it satisfies their ranges. This also applies to a filtered `pnpm --filter <project> add` [#​16432](https://redirect.github.com/pnpm/pnpm/issues/16432).
- `pnpm install` and `pnpm dedupe` now move an optional peer to the version already in the dependency graph when no other package provides its locked version anymore. After a bump such as `vue` 3.5.40 to 3.5.43, the lockfile kept a second copy of `@vue/server-renderer` for `@vue/test-utils` [#​16443](https://redirect.github.com/pnpm/pnpm/issues/16443).
- `pnpm dedupe --check` no longer fails right after `pnpm install` when a project's optional peer is satisfied by a package another workspace project installs. `pnpm dedupe` now picks the same versions for that package's dependencies as `pnpm install` [#​16447](https://redirect.github.com/pnpm/pnpm/issues/16447).
- `pnpm install` no longer re-resolves an up-to-date lockfile on every run when a patched package is a peer in a peer cycle [#​16418](https://redirect.github.com/pnpm/pnpm/issues/16418).
- With `autoDedupe` enabled, `pnpm install --lockfile-only` no longer resolves the dependency graph again when nothing changed since an earlier `--lockfile-only` install deduplicated the lockfile. Such an install keeps the lockfile even if versions were published since it was written, or if only a setting such as `resolutionMode` changed. Run `pnpm dedupe` to apply such a change [#​16458](https://redirect.github.com/pnpm/pnpm/issues/16458).
##### Speed and network
- A repeat `pnpm install` in a large workspace reports "Already up to date" faster [#​16487](https://redirect.github.com/pnpm/pnpm/issues/16487).
- Sped up dependency resolution of workspaces with many peer dependencies.
- `pnpm install` sends fewer registry metadata requests when the lockfile already decides which version a range resolves to. This now also covers ranges that several locked versions satisfy when one of them outranks the others, and direct dependencies kept at their locked version. Packages that `minimumReleaseAgeExclude` lists without a version now reuse cached registry metadata the same way they do when `minimumReleaseAge` is not set [#​16458](https://redirect.github.com/pnpm/pnpm/issues/16458).
- pnpm no longer downloads every packument again on each install from a registry whose metadata responses forbid caching, such as `Cache-Control: no-store`. pnpm revalidates the cached metadata with a conditional request, so a registry that supports conditional requests answers with a 304 when the package has not changed [#​16528](https://redirect.github.com/pnpm/pnpm/issues/16528).
- Cached metadata for a package published within `minimumReleaseAge` is now revalidated with its ETag, so the npm registry can answer `304 Not Modified`. Before, the next install that checked the cache downloaded the whole document again [#​16506](https://redirect.github.com/pnpm/pnpm/issues/16506).
- A fetch timeout while other downloads from the same host are still running now lowers concurrency for that host to one connection. Retries of that request, and later downloads from that host, use the lower concurrency. Other hosts keep the configured concurrency [#​12791](https://redirect.github.com/pnpm/pnpm/issues/12791).
- Sped up `pnpm install --offline` when the version a range picks is not in the store. While it looks for a version the store holds, pnpm now reads only the versions the range admits [#​16495](https://redirect.github.com/pnpm/pnpm/issues/16495).
- `pnpm install --offline` now reuses config dependency tarballs that are already present in the store [pnpm/tasks#46](https://redirect.github.com/pnpm/tasks/issues/46).
##### Running scripts
- `pnpm -s <script>` runs the script again, with `-s` meaning `--sequential` as it does for `pnpm run -s <script>`. pnpm rejected it with "unexpected argument '-s' found" [#​16446](https://redirect.github.com/pnpm/pnpm/issues/16446).
- `pnpm run` and `pnpm exec` now warn and run the command when the install that `verifyDepsBeforeRun` starts fails. This lets scripts run in sandboxes where pnpm cannot install, such as containers with a read-only store or no network [#​15173](https://redirect.github.com/pnpm/pnpm/issues/15173).
- A filtered `pnpm run` or `pnpm exec` now finds dependencies out of date when a workspace dependency of a selected project has no `node_modules` directory, as after a filtered install. With `verifyDepsBeforeRun: install`, pnpm installs that dependency before running the command [pnpm/tasks#45](https://redirect.github.com/pnpm/tasks/issues/45).
- Scripts run without a terminal no longer start a second `sh` each. One watchdog per pnpm command now ends every script's process group if pnpm is killed, so `pnpm -r run` across many projects starts half as many processes [#​16489](https://redirect.github.com/pnpm/pnpm/issues/16489).
- `Terminate batch job (Y/N)?` no longer appears after pressing Ctrl+C in a script started with `pnpm` from PowerShell or cmd on Windows [#​16502](https://redirect.github.com/pnpm/pnpm/issues/16502).
- `pnpm rebuild` and `pnpm approve-builds` refresh command launchers when a build changes a command's interpreter or replaces it with a native executable. Dependent packages' build scripts use the refreshed launchers.
- When `pnpm run <script>` or `pnpm <script>` finds nothing to run and `--filter` follows the script name, the error now suggests putting the filter option before the script name [#​4655](https://redirect.github.com/pnpm/pnpm/issues/4655).
- Package-name filters now support `?` to match one character [#​2817](https://redirect.github.com/pnpm/pnpm/issues/2817).
##### The pinned pnpm and `pnpm self-update`
- pnpm no longer downloads the project's pinned pnpm version again on every command when `nodeVersion` in `pnpm-workspace.yaml` names a different Node.js major than the `node` on `PATH`. Before, each of those commands took about a second longer and failed without network access [#​16497](https://redirect.github.com/pnpm/pnpm/issues/16497).
- Several `pnpm` commands started at once in a project that pins `packageManager` no longer fail with `The process cannot access the file because it is being used by another process` on Windows while the pinned pnpm is being installed.
- pnpm can now switch to a `packageManager` version below 11 on x64 musl Linux, such as Alpine [#​16467](https://redirect.github.com/pnpm/pnpm/issues/16467).
- A `devEngines.packageManager` range no longer makes pnpm replace the version recorded in `pnpm-lock.yaml` with the running pnpm while the recorded version still satisfies the range. When pnpm does record a version, it records the running pnpm only if it meets `minimumReleaseAge`. Otherwise it records the newest version in the range that meets it, or the running pnpm if none does [#​16431](https://redirect.github.com/pnpm/pnpm/issues/16431).
- On Windows, `pnpm self-update` now replaces a `pnpm.exe` left in `PNPM_HOME` or in `PNPM_HOME\bin`. Windows ran that executable in place of the updated `pnpm.cmd` shim, so `pnpm --version` kept printing the old version after a successful update. If the executable was in `PNPM_HOME`, `self-update` now asks you to run `pnpm setup` [#​9094](https://redirect.github.com/pnpm/pnpm/issues/9094).
- `pnpm self-update` now checks that a version installed as the JavaScript `pnpm` can start before making it the global `pnpm`. If Node.js is missing, the update fails and the current `pnpm` stays in place.
##### Other commands
- `pnpm deploy` now finds patches and local dependencies when the target directory sits under a symlink, such as `/tmp` on macOS. It failed with `ERR_PNPM_PATCH_NOT_FOUND` [#​16470](https://redirect.github.com/pnpm/pnpm/issues/16470).
- `pnpm deploy --legacy` now resolves the deployed project's relative `file:`, `link:`, and path dependencies from the project's own directory [#​16475](https://redirect.github.com/pnpm/pnpm/issues/16475).
- `pnpm update --global` now removes hard-linked executables from `PNPM_HOME` when migrating packages from the old global layout [#​16420](https://redirect.github.com/pnpm/pnpm/issues/16420).
- `pnpm store prune` no longer fails on store index entries that pnpm 11 wrote for git-hosted packages without a `package.json`. Entries that still cannot be read are kept and counted in the prune summary.
- `pnpm store prune` now aborts when an error other than a missing directory occurs while scanning project directories in the mark phase.
- `pnpm config get` and `pnpm config list` now report a setting given on the command line with `--config.<name>=<value>`. Before, a value such as `--config.node-linker=hoisted` reached the install but was absent from the reported configuration [#​16276](https://redirect.github.com/pnpm/pnpm/issues/16276).
- `pnpm -r pkg get` now reports every selected project when several share a package name. Projects with the same name are keyed by their directory relative to the workspace root. Before, only one of them appeared in the output.
- The install summary shows a `link:` dependency as `+ name <- path`, and the Node.js API's `hideLinkedPkgsDiff` reporter option leaves matching linked dependencies out of the summary.
- The `--force` help text of `pnpm install` and `pnpm add` now says that `--force` keeps skipping optional dependencies built for other platforms. It points to `forceIgnoresPlatform` and the `--os`, `--cpu`, and `--libc` options for installing them [#​16435](https://redirect.github.com/pnpm/pnpm/issues/16435).
- The `homepage` field of the published `pnpm` package points to <https://pnpm.io> again.
<!-- sponsors -->
#### Platinum Sponsors
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a>
</td>
<td align="center" valign="middle">
<a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/openai_dark.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/openai_light.svg" />
<img src="https://pnpm.io/img/users/openai_dark.svg" width="160" alt="OpenAI" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://notion.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion"></a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" />
<img src="https://pnpm.io/img/users/coderabbit.svg" width="220" alt="CodeRabbit" />
</picture>
</a>
</td>
</tr>
</tbody>
</table>
#### Gold Sponsors
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/sanity.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/sanity_light.svg" />
<img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" />
<img src="https://pnpm.io/img/users/discord.svg" width="220" alt="Discord" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/serpapi_dark.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/serpapi_light.svg" />
<img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160" alt="SerpApi" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/stackblitz.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/stackblitz_light.svg" />
<img src="https://pnpm.io/img/users/stackblitz.svg" width="190" alt="Stackblitz" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/workleap.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/workleap_light.svg" />
<img src="https://pnpm.io/img/users/workleap.svg" width="190" alt="Workleap" />
</picture>
</a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" />
<img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a>
</td>
</tr>
</tbody>
</table>
<!-- sponsors end -->
### [`v12.8.2`](https://redirect.github.com/pnpm/pnpm/releases/tag/v12.8.2): pnpm 12.8.2
[Compare Source](https://redirect.github.com/pnpm/pnpm/compare/v12.8.1...v12.8.2)
pnpm 12.8.2 fixes a startup crash on Linux ppc64le and `UnknownIssuer` errors on systems without CA certificates. `pnpm run` no longer installs before every script on CI when `autoDedupe` is enabled, and resolution and hoisted installs on macOS are faster.
##### Patch Changes
##### Platforms and environments
- Fixed pnpm crashing on startup on Linux ppc64le [#​16380](https://redirect.github.com/pnpm/pnpm/issues/16380).
- Fixed installs failing with `UnknownIssuer` on Linux systems without CA certificates, such as `node:24-slim`, when `NODE_EXTRA_CA_CERTS` is set. The extra certificates now extend the bundled CA roots [#​16365](https://redirect.github.com/pnpm/pnpm/issues/16365).
- pnpm now creates its store operation locks and other per-user lock files in `$XDG_RUNTIME_DIR` when it points to a directory only the user can write to. Otherwise, pnpm still uses `/tmp` on Linux and macOS. Sandboxes that block writes to `/tmp` can point `XDG_RUNTIME_DIR` at a writable directory [#​16390](https://redirect.github.com/pnpm/pnpm/issues/16390).
- POSIX bin shims and the `pnpm`, `pn`, `pnpx`, and `pnx` launchers now run inside a Nix build, where the system default path holds none of the utilities they call. Installing again replaces the shims already in `node_modules` [#​16377](https://redirect.github.com/pnpm/pnpm/issues/16377).
- In a project that pins another pnpm version, pnpm now passes a command with an option it does not know to the pinned version. Before, pnpm rejected the option before switching, so `pnpm install --auto-dedupe` failed with "Unknown option" even though the pinned pnpm supports it [#​16353](https://redirect.github.com/pnpm/pnpm/issues/16353).
##### Installing and resolving dependencies
- `pnpm install --frozen-lockfile` now fails when `Cargo.lock` does not satisfy a dependency requirement in `Cargo.toml`. The error names the crate and the version the lockfile holds [#​16355](https://redirect.github.com/pnpm/pnpm/issues/16355).
- `pnpm install` returns "Already up to date" again in a workspace with injected workspace dependencies and a shared lockfile. Since 12.7.0 every repeat install in such a workspace ran the full install and copied the injected projects again.
- With `injectWorkspacePackages: true`, a fresh `pnpm install` now records a workspace dependency as `link:` when its injected copy differs from the project only by an optional peer that peer-dependent dedupe merges. It was recorded as a peer-suffixed `file:` copy [#​16354](https://redirect.github.com/pnpm/pnpm/issues/16354).
- `pnpm dedupe --check` now passes right after `pnpm dedupe` when deduplication merges variants of a package that differ only in their peers. A lockfile key whose peer suffix named a merged variant now names the variant that replaced it [#​16356](https://redirect.github.com/pnpm/pnpm/issues/16356).
- When `minimumReleaseAge` hides the version that `latest` points to, pnpm now falls back to a prerelease of the same major before a stable version of an older major. A stable version of the same major is still preferred. Before, while a new `1.0.0` was too new, `latest` fell back to an old `0.0.1` even though `1.0.0-beta.4` had been `latest` until then [#​16388](https://redirect.github.com/pnpm/pnpm/issues/16388).
- Git-hosted dependencies now respect `pmOnFail`. If it is set to anything other than `download`, a git-hosted dependency that pins a pnpm version is prepared by the running pnpm, and pnpm does not download the pinned version [#​16376](https://redirect.github.com/pnpm/pnpm/issues/16376).
- pnpmfile hooks such as `readPackage` now run once for a dependency that several packages request at the same time. They could run twice for it before.
- `childConcurrency` now defaults to 5, the documented value. It used to be capped at 4 and to follow the host's CPU count.
##### Running scripts
- `pnpm run` and `pnpm exec` no longer install dependencies before every script on CI when `autoDedupe` is enabled. `pnpm install --frozen-lockfile` now keeps the deduplication record left by an earlier install [#​16374](https://redirect.github.com/pnpm/pnpm/issues/16374).
- On macOS and Linux, lifecycle scripts and `pnpm run` now always get `PATH` from the `PATH` variable. When the environment also held a `Path` variable, a script sometimes got `Path`'s value, and failed with `node: not found` [#​16308](https://redirect.github.com/pnpm/pnpm/issues/16308).
- `pnpm run` now exits after a `SIGTERM` in a container where pnpm is PID 1 and the script runs pnpm again, as `"start": "pnpm serve"` does. Since 12.6.0 it kept waiting after the script had shut down, until the container runtime killed it.
##### Other commands and settings
- `pnpm config get globalShims`, `pnpm shim list`, and global installs no longer read `globalShims` from a project's `pnpm-workspace.yaml`. Only the global config file, the pnpm home's own `pnpm-workspace.yaml`, and `PNPM_CONFIG_GLOBAL_SHIMS` set it, so a repository cannot choose which globally installed packages get project-aware shims.
- `pnpm config set --location=project` refuses a machine-level setting such as `stateDir` or `scope` with `ERR_PNPM_CONFIG_SET_NOT_A_PROJECT_SETTING`, which names where the setting belongs. `pnpm config delete` still clears such a key from a project's `pnpm-workspace.yaml`.
- `pnpm deploy` no longer fails with `ERR_PNPM_DEPLOY_AMBIGUOUS_PEER` in a workspace with `injectWorkspacePackages: true` when a workspace package lists its peer dependency as a dev dependency too [#​16375](https://redirect.github.com/pnpm/pnpm/issues/16375).
- `pnpm deploy` no longer copies the workspace root's `packageManager` and `devEngines.packageManager` fields into the deployed `package.json` [#​16403](https://redirect.github.com/pnpm/pnpm/issues/16403).
- `pnpm publish` now includes bare `README` files and README files with Markdown extensions such as `readme.markdown` in registry metadata [#​12704](https://redirect.github.com/pnpm/pnpm/issues/12704).
- `pnpm store prune` now removes the packages that only expired `pnpm dlx` cache entries used. They were left in the store until the next `pnpm store prune` [#​16383](https://redirect.github.com/pnpm/pnpm/discussions/16383).
##### Performance
- Sped up dependency resolution in large workspaces, and when many dependencies request different ranges of the same package. Resolution also uses less memory.
- Sped up `pnpm install` with `nodeLinker: hoisted` on macOS when the lockfile is re-resolved, such as with `autoDedupe` enabled [#​16397](https://redirect.github.com/pnpm/pnpm/issues/16397).
- Sped up extracting package tarballs.
- `pnpm install` without `--frozen-lockfile` is faster on some machines in projects with a `pnpm-workspace.yaml`. Those installs linked with one worker thread per core, half of what a frozen install uses.
- On Windows, warm `pnpm install --frozen-lockfile` runs are 4-5% faster on 4- and 8-core machines. pnpm now links with one worker thread per core on Windows, between 4 and 16. This changes frozen installs and installs in projects without a `pnpm-workspace.yaml` on machines with 3 to 15 cores.
<!-- sponsors -->
#### Platinum Sponsors
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a>
</td>
<td align="center" valign="middle">
<a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/openai_dark.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/openai_light.svg" />
<img src="https://pnpm.io/img/users/openai_dark.svg" width="160" alt="OpenAI" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://notion.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion"></a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" />
<img src="https://pnpm.io/img/users/coderabbit.svg" width="220" alt="CodeRabbit" />
</picture>
</a>
</td>
</tr>
</tbody>
</table>
#### Gold Sponsors
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/sanity.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/sanity_light.svg" />
<img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" />
<img src="https://pnpm.io/img/users/discord.svg" width="220" alt="Discord" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/serpapi_dark.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/serpapi_light.svg" />
<img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160" alt="SerpApi" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/stackblitz.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/stackblitz_light.svg" />
<img src="https://pnpm.io/img/users/stackblitz.svg" width="190" alt="Stackblitz" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/workleap.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/workleap_light.svg" />
<img src="https://pnpm.io/img/users/workleap.svg" width="190" alt="Workleap" />
</picture>
</a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" />
<img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a>
</td>
</tr>
</tbody>
</table>
<!-- sponsors end -->
### [`v12.8.1`](https://redirect.github.com/pnpm/pnpm/releases/tag/v12.8.1): pnpm 12.8.1
[Compare Source](https://redirect.github.com/pnpm/pnpm/compare/pnpm@12.8.0...v12.8.1)
pnpm 12.8.1 fixes `pnpm install --frozen-lockfile` rejecting lockfiles with injected workspace packages that have peers, restores the executable bit on files of local directory dependencies, makes `pnpm dedupe` converge, and uses less CPU on many-core machines.
##### Patch Changes
- `pnpm install --frozen-lockfile` no longer rejects a freshly generated lockfile when an injected workspace package has peer dependencies [#​16332](https://redirect.github.com/pnpm/pnpm/issues/16332).
- Executable files in a `file:` directory dependency or an injected workspace package keep their executable bit again. Since 12.8.0, pnpm installed these files without the permissions they have in their project.
- `pnpm dedupe` now reaches a stable lockfile when a package's peer suffix is long enough to be hashed. Before, each run could switch that package's key between the hashed and the spelled-out suffix, so `pnpm dedupe --check` always failed [#​16331](https://redirect.github.com/pnpm/pnpm/issues/16331).
- `pnpm install --frozen-lockfile`, the default in CI, now uses less CPU on machines with more than 8 cores. Warm installs on many-core Windows machines got up to 10% faster. Frozen installs now link with at most 16 worker threads.
- `verifyDepsBeforeRun` no longer reports dependencies as outdated after a filtered install just because `pnpm-lock.yaml` has a newer modification time. It checks the lockfile against the packages that install put in place. Before, `pnpm run` reinstalled the whole workspace with lifecycle scripts on, for example after a Docker `COPY` brought in a lockfile with a newer mtime [#​16322](https://redirect.github.com/pnpm/pnpm/issues/16322).
After a filtered install, `verifyDepsBeforeRun` now also checks that the install put the selected projects' dependencies in place. A `node_modules` directory alone no longer counts as proof.
- `pnpm run` and `pnpm exec` no longer install a project that has never been installed and has nothing to install. Such a project declares no dependencies, no peer dependencies that `autoInstallPeers` would fetch, and no install lifecycle scripts. The command now runs without writing `node_modules` or `pnpm-lock.yaml` [#​16313](https://redirect.github.com/pnpm/pnpm/issues/16313).
- `pnpm update -g --latest` now upgrades globally installed packages beyond their saved version ranges [#​16320](https://redirect.github.com/pnpm/pnpm/issues/16320).
<!-- sponsors -->
##### Platinum Sponsors
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a>
</td>
<td align="center" valign="middle">
<a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/openai_dark.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/openai_light.svg" />
<img src="https://pnpm.io/img/users/openai_dark.svg" width="160" alt="OpenAI" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://notion.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion"></a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" />
<img src="https://pnpm.io/img/users/coderabbit.svg" width="220" alt="CodeRabbit" />
</picture>
</a>
</td>
</tr>
</tbody>
</table>
##### Gold Sponsors
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/sanity.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/sanity_light.svg" />
<img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" />
<img src="https://pnpm.io/img/users/discord.svg" width="220" alt="Discord" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/serpapi_dark.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/serpapi_light.svg" />
<img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160" alt="SerpApi" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/stackblitz.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/stackblitz_light.svg" />
<img src="https://pnpm.io/img/users/stackblitz.svg" width="190" alt="Stackblitz" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/workleap.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/workleap_light.svg" />
<img src="https://pnpm.io/img/users/workleap.svg" width="190" alt="Workleap" />
</picture>
</a>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" />
<source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" />
<img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" />
</picture>
</a>
</td>
<td align="center" valign="middle">
<a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a>
</td>
</tr>
</tbody>
</table>
<!-- sponsors end -->
### [`v12.8.0`](https://redirect.github.com/pnpm/pnpm/releases/tag/v12.8.0): pnpm 12.8
[Compare Source](https://redirect.github.com/pnpm/pnpm/compare/v12.7.0...pnpm@12.8.0)
pnpm 12.8.0 warns when `pnpm pack` or `pnpm publish` would ship a `.env` file that `files` does not list, installs `sharedWorkspaceLockfile: false` workspaces concurrently, applies every setting passed as `--config.<name>=<value>`, and no longer leaves the Windows terminal stuck after Ctrl+C in a script.
##### Minor Changes
- `pnpm pack` and `pnpm publish` now warn when the tarball includes a `.env` or `.env.*` file that the `files` field of `package.json` does not list. Templates such as `.env.example` are not reported. List the file in `files` to publish it on purpose, or exclude it in `.npmignore` or `.gitignore` [#​7826](https://redirect.github.com/pnpm/pnpm/issues/7826).
- `pnpm pack` now honors `--silent`, `--reporter=silent`, and `--loglevel=silent` to hide the tarball contents and summary. With `--json`, lifecycle script output and the final JSON output remain visible [#​10297](https://redirect.github.com/pnpm/pnpm/issues/10297).
##### Patch Changes
##### Installing packages
- Installing through a `pnpr` server now records the pnpmfile checksum in the lockfile, so a later `pnpm install --frozen-lockfile` accepts that lockfile [#​14460](https://redirect.github.com/pnpm/pnpm/issues/14460). A frozen install through the pnpr server now fails if the pnpmfile changed. If the pnpmfile defines a `readPackage`, `afterAllResolved` or `preResolution` hook or custom resolvers, pnpm resolves dependencies locally and prints a warning that the pnpr server was not used.
Installing through a `pnpr` server also links a workspace project at the directory its `publishConfig.directory` names. A server that does not forward the setting makes the install fail with `ERR_PNPM_PNPR_PUBLISH_DIRECTORY_MISMATCH`, so pnpm never writes a lockfile that points at the wrong directory. The server rejects a `publishConfig.directory` that points outside its project.
- Installing a git-hosted dependency that has to be built no longer fails when that dependency's own dependencies have build scripts nobody approved. pnpm skips those builds while preparing the dependency, as it does without `strictDepBuilds` [#​9764](https://redirect.github.com/pnpm/pnpm/issues/9764).
- A git-hosted dependency that is a pnpm workspace with no committed lockfile is now detected as a pnpm project [#​14011](https://redirect.github.com/pnpm/pnpm/issues/14011).
- `pnpm install --dev` and `pnpm fetch --dev` now install the optional dependencies of devDependencies, such as the platform binaries of Biome and oxlint. The project's own `optionalDependencies` are still skipped [#​9678](https://redirect.github.com/pnpm/pnpm/issues/9678).
- `pnpm install --offline` and `pnpm add --offline` now resolve a version range to the newest matching version whose tarball is already in the store. They used to pick the newest version in the cached metadata and fail with `ERR_PNPM_NO_OFFLINE_TARBALL` when its tarball was missing [#​10715](https://redirect.github.com/pnpm/pnpm/issues/10715).
- If an offline install fails because the registry metadata cache uses the layout from before pnpm 11.27 and 12.4, the error now names the older mirror on disk and explains that one online install repopulates the cache. The error also carries the `ERR_PNPM_NO_OFFLINE_META` code. `pnpm cache prune --help` now says that pnpm 11.26 and earlier, and pnpm 12.3 and earlier, depend on the directories it removes [#​15656](https://redirect.github.com/pnpm/pnpm/issues/15656).
- Running `pnpm install` now refreshes dependencies when a package declared with a local `file:` directory changes its dependencies [#​4623](https://redirect.github.com/pnpm/pnpm/issues/4623).
- A repeat `pnpm install` now keeps its fast up-to-date check when an override replaces a declared local `file:` dependency [#​12892](https://redirect.github.com/pnpm/pnpm/issues/12892).
- `pnpm install` now removes an optional dependency from `node_modules` if its install script fails. Code that checks whether the package is installed no longer finds a package that cannot load [#​8756](https://redirect.github.com/pnpm/pnpm/issues/8756).
- With `nodeLinker: hoisted`, `pnpm install` now restores a workspace project's `node_modules` after it was deleted. Before, the install printed "Already up to date" and left the project without the dependencies nested under it. On Windows, the install also no longer fails with "Access is denied" when another project's copy of a shared dependency links to the deleted directory.
- Under `nodeLinker: hoisted`, `pnpm install` now clears orphaned package directories that an interrupted or failed install leaves in a project's `node_modules`. A directory recorded by the previous install is removed, while an unrecorded directory is moved to `node_modules/.ignored`. A copy already in `.ignored` is never overwritten [#​13676](https://redirect.github.com/pnpm/pnpm/issues/13676).
- Concurrent installs no longer fail when they replace the same stale hoisted dependency link. Virtual store cleanup now keeps the temporary lockfiles that concurrent installs write.
##### Resolving and linking dependencies
- `pnpm install` no longer aborts on a failed allocation of many gigabytes when peer dependency ranges combine overlapping `||` alternatives [#​15867](https://redirect.github.com/pnpm/pnpm/issues/15867).
- `pnpm install` no longer fails when a package from the registry declares a `file:` dependency on a directory inside itself, such as `"@types/css-tree": "file:./typings/css-tree"`. pnpm links that dependency to the directory inside the package, as npm and Yarn do. The lockfile records it as `link:<root>/typings/css-tree` [#​9141](https://redirect.github.com/pnpm/pnpm/issues/9141).
- An `npm:` alias written by `overrides` now stays in place when a change elsewhere makes pnpm re-resolve the aliased dependency. Before, pnpm could look up the alias name at the aliased version, which failed with `ERR_PNPM_NO_MATCHING_VERSION` or locked an unrelated package [#​16309](https://redirect.github.com/pnpm/pnpm/issues/16309).
- A peer dependency no longer resolves to two different versions for one package. This happened when the package peer-depends on another package and on one of that package's peers, and it is installed deeper than a direct dependency of the package that provides them [#​12098](https://redirect.github.com/pnpm/pnpm/issues/12098).
- An optional peer dependency is no longer resolved from another workspace project's package when the project provides one of that package's own peers at a version it rejects. This avoids bogus unmet peer errors [#​13989](https://redirect.github.com/pnpm/pnpm/issues/13989).
- `pnpm dedupe` no longer changes the lockfile on every run when a nested peer dependency is provided through an npm alias [#​15709](https://redirect.github.com/pnpm/pnpm/issues/15709).
- With `resolutionMode: time-based` and `minimumReleaseAge` both set, `pnpm install` no longer reports a subdependency as too new when only the time-based cutoff excludes it. Such subdependencies used to fail a strict install with `ERR_PNPM_NO_MATURE_MATCHING_VERSION`, or were added to `minimumReleaseAgeExclude` [#​13569](https://redirect.github.com/pnpm/pnpm/issues/13569). A transitive dependency that has no matching version published before the time-based cutoff now resolves to the lowest matching version allowed by `minimumReleaseAge`. pnpm picks a version younger than `minimumReleaseAge` only if no older version matches [#​16298](https://redirect.github.com/pnpm/pnpm/issues/16298).
- `pnpm install` retries registry metadata fetches that fail with a timeout, a dropped connection, or an interrupted response body before it applies `trustPolicy` or `minimumReleaseAge`. A transient fetch failure is not reported as `TRUST_DOWNGRADE` or `MINIMUM_RELEASE_AGE_VIOLATION` [#​12031](https://redirect.github.com/pnpm/pnpm/issues/12031).
- pnpm's built-in package compatibility database no longer applies to a project's own manifest. A project named like a published package, such as `vue-loader`, no longer gains dependencies on `pnpm install` or `pnpm update`. User-configured `packageExtensions` still apply to project manifests [#​11700](https://redirect.github.com/pnpm/pnpm/issues/11700).
- Packages in an external `virtualStoreDir` can resolve the project's direct dependencies selected by `hoistPattern`. Run `pnpm install --force` to repair an existing installation [#​5652](https://redirect.github.com/pnpm/pnpm/issues/5652).
- `pnpm install` now links the executables of auto-installed peer dependencies into the workspace root's `node_modules/.bin`, including after a frozen-lockfile reinstall [#​8511](https://redirect.github.com/pnpm/pnpm/issues/8511).
##### Lockfiles and frozen installs
- `pnpm install --frozen-lockfile` now works on a detached HEAD when `gitBranchLockfile` is enabled. The install reads the lockfiles of the local and remote-tracking branches that contain the checked-out commit. It still writes the shared `pnpm-lock.yaml` [#​7672](https://redirect.github.com/pnpm/pnpm/issues/7672).
- `pnpm install --frozen-lockfile` now accepts a lockfile that has no importer entry for a workspace package without dependencies. Such a package added after the lockfile was written made the install fail with `ERR_PNPM_PACKAGE_MANAGER_NO_IMPORTER` [#​15875](https://redirect.github.com/pnpm/pnpm/issues/15875).
- `pnpm install` now fails with `ERR_PNPM_LOCKFILE_MISSING_DEPENDENCY` when an importer references a dependency version that has no snapshot entry. Before, the install succeeded and left a `node_modules` symlink pointing at a missing virtual-store directory [#​14764](https://redirect.github.com/pnpm/pnpm/issues/14764).
- `pnpm install` on CI now fails on an outdated lockfile when `preferFrozenLockfile` is explicitly set to `true`. Setting it to `true` used to let CI update the lockfile [#​9072](https://redirect.github.com/pnpm/pnpm/pull/9072).
- With `gitBranchLockfile` enabled, each emoji or other character outside the Basic Multilingual Plane in a branch name now becomes `!!` in the lockfile name. Before, each such character became one `!`.
##### Workspaces and filtering
- `pnpm install` in a workspace with `sharedWorkspaceLockfile: false` now installs projects concurrently, up to `workspaceConcurrency` at a time [#​14480](https://redirect.github.com/pnpm/pnpm/issues/14480). A project is resolved, fetched, and written to its virtual store without waiting for the workspace projects it depends on. It waits for them only before it links its dependencies and runs its lifecycle scripts, so its scripts still run after theirs. A project with a `preinstall` or `pnpm:devPreinstall` script, or with an injected or `file:` workspace dependency, waits for its workspace dependencies before it starts.
The installs of the projects also share their package metadata, lockfile verification, and store caches, so they use less CPU and memory when several projects depend on the same packages. An install with a pnpmfile no longer starts an extra Node.js process when the pnpmfile has no `preResolution` hook.
- With `enableGlobalVirtualStore` and `sharedWorkspaceLockfile: false`, each project now keeps its current lockfile and its hidden hoisted dependencies in its own `node_modules/.pnpm`. Before, every project wrote them to the workspace root's `node_modules/.pnpm`, so each repeat install treated the other projects' packages as its own and relinked them [#​14480](https://redirect.github.com/pnpm/pnpm/issues/14480).
- `pnpm rebuild`, `pnpm approve-builds`, and `pnpm ignored-builds` now work on the current project's `node_modules` when they run inside a project of a workspace with `sharedWorkspaceLockfile: false`. They used to read the workspace root's `node_modules`, so `pnpm rebuild` did not rebuild the project's dependencies and created a second virtual store at the workspace root [#​9402](https://redirect.github.com/pnpm/pnpm/issues/9402).
- `pnpm install` no longer creates a `node_modules` symlink inside the `publishConfig.directory` of a workspace package linked with `linkDirectory`. A build tool that cleaned its output directory through that symlink deleted the files of the package's dependencies. `pnpm install` also removes a symlink that an earlier install left there [#​16226](https://redirect.github.com/pnpm/pnpm/issues/16226). It also no longer fails with `ERR_PNPM_CMD_SHIM_RESOLVE_PATH` when such a package has a `bin` field and its `publishConfig.directory` does not exist yet.
- `pnpm install` no longer fails for an injected workspace dependency whose package publishes from a `publishConfig.directory` that its own `prepare` script builds. The injected copy now picks up that directory once `prepare` finishes building it. `pnpm install --frozen-lockfile` no longer reports the dependency as outdated while the directory has not been built yet [#​7811](https://redirect.github.com/pnpm/pnpm/issues/7811).
- An in-place edit to the source of an injected workspace package now shows up in its injected copy, unless a build writes to that package or `packageImportMethod` is set. pnpm hardlinks such packages under the default import method [#​4410](https://redirect.github.com/pnpm/pnpm/issues/4410). Scripts listed in `syncInjectedDepsAfterScripts` now update injected dependencies while they run, so a watcher on the injected package, such as a dev server, sees each change before the script exits.
- With `sharedWorkspaceLockfile: false`, an injected workspace package that has lifecycle scripts is now hard linked into the projects that depend on it. Before, pnpm left a plain copy, so later edits to the package did not reach those projects [#​9828](https://redirect.github.com/pnpm/pnpm/issues/9828).
- `injectWorkspacePackages` now hard links a workspace dependency declared with a relative path, such as `workspace:../foo`, the same way it already does for `workspace:*` [#​10446](https://redirect.g
> ❗ **Important**
>
> ✂ PR body was truncated to here.
</details>
---
### Configuration
📅 **Schedule**: (in timezone Etc/UTC)
- Branch creation
- "every weekend"
- Automerge
- "after 1 am and before 7 am"
🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/canonical/craft-actions).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMjUuMSIsInVwZGF0ZWRJblZlciI6IjQ0LjEyNS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJQUjogRGVwZW5kZW5jaWVzIl19-->
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| ~deepseek/deepseek-pro-latest | — | closed resolved | Merged Renovate PR updating pnpm from 12.6.0 to 12.9.0 in package.json and pnpm-lock.yaml. | |
| ~deepseek/deepseek-pro-latest | — | closed resolved | Merged Renovate PR updating pnpm from 12.6.0 to 12.9.0, bumping packageManager and lockfile. | |
| stealth/space-bunny-alpha |
Impact:
22
Quick Win:
17
Complexity:
10
Confidence:
88
Actionability:
85
|
needs review | Renovate bumps pnpm 12.6.0 → 12.9.0 in package.json and pnpm-lock.yaml (+62/-62). All 14 CI checks pass, no reviewers yet, no comments; routine toolchain-only dependency update. | |
| stealth/space-bunny-alpha |
Impact:
28
Quick Win:
19
Complexity:
15
Confidence:
86
Actionability:
80
|
needs review | Renovate bumps pnpm 12.6.0 → 12.8.2 via the packageManager field in package.json and the pnpm-lock.yaml; all CI checks pass, no reviewer comments yet, and automerge is disabled by config. | |
| stealth/space-bunny-alpha |
Impact:
18
Quick Win:
13
Complexity:
10
Confidence:
88
Actionability:
82
|
needs review | Renovate bump of pnpm 12.6.0 → 12.8.1 in package.json and pnpm-lock.yaml (build tooling only). All 16 CI checks green, no review comments, awaiting maintainer merge since automerge is disabled by config. |
Update history
| Date | Change |
|---|---|
| updated | |
| merged | |
| updated | |
| updated | |
| created |
Related issues
| Issue | Project | State | Summary | Similarity |
|---|---|---|---|---|
| #129 chore(deps): update pnpm to v12.11.2 | craft-actions | merged | Updated pnpm dependency from 12.9.0 to 12.11.2 via automated Renovate PR #129. All CI checks passed and the PR was merged. | |
| #114 chore(deps): update pnpm to v12.4.1 | craft-actions | closed | Renovate PR merged as commit 31eead4, bumping pnpm 12.3.4 → 12.4.1 in package.json/pnpm-lock.yaml (+95/-38) with all CI checks passing. | |
| #133 chore(deps): update pnpm to v12.14.0 | craft-actions | merged | Merged into main via #133, updating pnpm from 12.11.2 to 12.14.0 with performance and stability improvements. | |
| #124 chore(deps): update pnpm to v12.6.0 | craft-actions | merged | Merged canonical/craft-actions#124, updating pnpm from 12.4.1 to 12.6.0 in package.json and pnpm-lock.yaml. | |
| #109 chore(deps): update pnpm to v11.25.0 | craft-actions | merged | Renovate PR merged into main, bumping pnpm 11.24.0 -> 11.25.0 in package.json (1-line diff), approved by a maintainer with all CI checks green. | |
| #90 chore(deps): update pnpm to v11.22.0 | craft-actions | merged | Renovate PR merged into main, bumping pnpm 11.20.0 -> 11.22.0 in commit 79b2779 (one-line packageManager change), after approval and green CI. | |
| #84 chore(deps): update pnpm to v11.18.0 | craft-actions | merged | Renovate PR #84 bumping pnpm 11.11.0 → 11.18.0 in package.json (1 file, +1/-1) was merged into main with one approval and all CI checks passing. | |
| #75 chore(deps): update pnpm to v11.11.0 | craft-actions | merged | Merged pnpm 11.9.0 → 11.11.0 via package.json in commit ac5eb23. | |
| #88 chore(deps): update pnpm to v11.20.0 | craft-actions | merged | Renovate PR merged as commit bf4fac9, bumping pnpm 11.18.0 -> 11.20.0 in package.json (packageManager field) after CLA approval and all CI checks passed. Followed by #90, #109, #112, #114, #124. | |
| #118 chore(deps): update pnpm to v12.4.2 | craft-actions | closed | Closed unmerged; pnpm was not advanced from 12.4.1 to 12.4.2, and no merge, replacement, approval, or maintainer explanation was recorded. |