Files
pnpm/pacquet
Zoltan Kochan a1f6f32996 fix(pacquet/package-manager): build workspace state from project list, not lockfile (#11946)
`build_projects_map` derived workspace projects from `lockfile.importers.keys()`. On the fresh-install path the wanted lockfile is `None` (no `pnpm-lock.yaml` on disk yet), so the function fell into its no-lockfile arm and recorded **only the root importer** — even for an 87-project workspace like babylon.

That broke the [`optimistic_repeat_install`](https://github.com/pnpm/pnpm/blob/6b3ba4d337/pacquet/crates/package-manager/src/optimistic_repeat_install.rs) fast path on the *next* install: `project_structure_matches` compared the recorded project list (`len = 1`) against the workspace projects the resolver discovered (`len = 87`), returned `false`, and the install fell through to the full resolve + verify path even though the on-disk state was already a no-op.

## Fix

Upstream pnpm's [`createWorkspaceState`](https://github.com/pnpm/pnpm/blob/cc4ff817aa/workspace/state/src/createWorkspaceState.ts#L14-L27) takes `allProjects: ProjectsList` as input and emits one entry per project — the lockfile isn't involved. Pacquet already builds the matching `project_manifests: &[(PathBuf, &PackageManifest)]` at the top of `Install::run` (for the optimistic-repeat fast path); thread it through to `build_workspace_state` instead of re-deriving from the lockfile.

The new `build_projects_map` is half the size of the old one and can't fall into a "lockfile missing" arm — the project list always comes from the same scan the rest of the install uses.

## Impact

Re-bench against the vlt `babylon` fixture (87-project monorepo) shows every `*+node_modules` cell collapsing from "very slow" to "faster than pnpm":

| Variation | Before | After |
|---|---:|---:|
| `node_modules` | 37.87× | **0.09×** (11× faster than pnpm) |
| `lockfile+node_modules` | 25.52× | **0.07×** (14× faster) |
| `cache+node_modules` | 11.55× | **0.15×** (6.7× faster) |
| `cache+lockfile+node_modules` | 11.35× | **0.17×** (5.9× faster) |

These were the four worst cells in the vlt benchmark chart for babylon (all flagged DNF before #11944 fixed the underlying panic). After #11944 babylon stopped DNF'ing but stayed 11-37× slower because of this workspace-state writing bug.

The fast path only failed for workspace installs whose wanted lockfile was absent on the first install of the iteration — i.e. exactly the vlt benchmark's `node_modules` and `*+node_modules` shape. Single-project installs always recorded the root correctly because the no-lockfile fallback already emitted the root entry.

Found while validating #11944's claim that the babylon DNF cells would collapse on the next pacquet release (#11902).
2026-05-26 02:24:13 +02:00
..
2026-04-30 16:35:57 +02:00

pacquet

Warning

pacquet is under active development and not yet ready for production use.

The official pnpm rewrite in Rust.

pacquet is a port of the pnpm CLI from TypeScript to Rust. It is not a new package manager and not a reimagining of pnpm. Its behavior, flags, defaults, error codes, file formats, and directory layout will match pnpm exactly.

Roadmap

pacquet will become the installation engine of pnpm. The transition will happen in two phases.

Phase 1: fetching and linking

pacquet replaces fetching and linking only. pnpm continues to create the lockfile, and pacquet does the rest. We expect this alone to make pnpm at least twice as fast in most scenarios. Shipping this phase is the current focus.

Phase 2: resolution

pacquet also takes over dependency resolution.

See CONTRIBUTING.md for development setup, debugging, testing, and benchmarking.

Benchmark