Files
pnpm/installing
Sharmila 1c73e8303c fix(deps-resolver): prefer locked peer contexts during resolution by default (#12083)
## Summary

Preserve compatible peer contexts already recorded in the lockfile during a
writable re-resolution.

A fresh install still resolves peers normally. When a lockfile already records
multiple valid peer contexts, pnpm keeps those contexts instead of collapsing
them into one compatible context and rewriting unrelated lockfile entries.

## Why

[#12075](https://github.com/pnpm/pnpm/pull/12075) fixed optional-peer candidate
selection: pnpm no longer discards a compatible optional-peer version merely
because it came from the lockfile.

This PR addresses a separate source of lockfile churn. A writable install could
still replace one valid peer context with another valid peer context even when
the existing provider remained present and satisfied the peer range.

Public reproduction:
<https://github.com/sharmila-oai/pnpm-optional-peer-lockfile-repro>

The nested reproduction starts with two valid `vitest@3.2.4` contexts:

```text
context-low  -> vitest@3.2.4(jsdom@26.1.0)
context-high -> vitest@3.2.4(jsdom@27.4.0)
```

Running a writable lockfile regeneration should retain both contexts:

```sh
./reproduce-nested-context.sh
```

## Behavior

pnpm reuses a locked peer provider only when:

- The provider is still present in the current dependency graph.
- The provider still satisfies the peer range.

Current manifest choices remain authoritative. In particular, pnpm does not
replace:

- A newly added direct peer provider.
- An explicitly updated direct peer provider.
- A changed nested provider.
- A direct provider installed through an alias.

The reuse pass runs only when the dependency tree contains locked peer contexts,
so fresh installs do not pay for a second peer-resolution pass.

## Tradeoff

This change favors lockfile stability over reducing the number of peer
contexts. A writable install may retain multiple compatible peer contexts where
a fresh install would select one.

## Implementation

The resolver performs its normal peer-resolution pass first. When the
dependency tree contains locked peer contexts, it performs a second pass that
may reuse compatible provider paths from the lockfile while respecting current
manifest choices.

pacquet now mirrors this behavior. Its lockfile-reuse path rebuilds child
dependencies from the package manifest and skips peer dependencies recorded in
the snapshot, so the peer pass derives each dependency instance's peer context.

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-06-02 22:02:57 +02:00
..
2026-05-29 17:26:13 +02:00
2026-06-02 08:07:46 +02:00
2026-05-29 17:26:13 +02:00
2026-05-27 15:15:01 +02:00
2026-05-29 17:26:13 +02:00