Skip to content

pacquet: resolve all workspace projects in the fresh-resolve install path #11901

Description

@zkochan

Summary

pacquet install (no --frozen-lockfile, no usable lockfile) in a pnpm-workspace.yaml repo only resolves the workspace root manifest. Transitive workspace projects' own dependencies are not resolved into the lockfile. This makes pacquet effectively unusable for monorepos in the fresh-resolve path and is the dominant factor in the babylon benchmark's 4-7× slowdown across all variations.

Benchmark evidence

From benchmarks.vlt.sh/latest/chart-data.jsonbabylon is a pnpm-workspace.yaml monorepo (Babylon.js 3D engine, 86+ packages):

Variation pnpm pacquet ratio
clean 23.68s 99.51s 4.2× slower
cache 21.60s 52.70s 2.4× slower
lockfile 16.12s 100.42s 6.2× slower
node_modules 26.13s 99.23s 3.8× slower
cache+lockfile 7.96s 43.65s 5.5× slower
cache+lockfile+node_modules 0.72s 3.05s 4.2× slower

Compare with next (single project) where pacquet wins or ties: the slowdown is specifically a workspace-monorepo phenomenon in the fresh-resolve dispatch.

Current pacquet behavior

After the dispatch at pacquet/crates/package-manager/src/install.rs#L660-L699, the fresh branch passes a single &PackageManifest (the workspace root) into InstallWithFreshLockfile. The code self-documents the gap:

Pacquet's fresh-resolve path has one importer today (workspaces tracked at pnpm/pacquet#431), so the workspace root is the only path to register.

build_workspace_packages_map does load sibling workspace projects so the workspace: protocol resolves, but their own dependencies / devDependencies aren't walked.

Proposed approach

Match pnpm's installing/deps-installer/src/install/index.ts pattern: collect every workspace project's manifest into an importers list, hand the whole list to the resolver, and run one unified tree walk. Transitive packages that multiple workspace projects share get resolved once and deduped via pkgIdsByName.

This is Stage 2 Tier 1 of #11633 ("Resolution graph & recursion engine"), but worth tracking as its own concrete issue because:

  • the file/line where the single-importer assumption is hard-coded is known and small;
  • it's the dominant factor in one entire fixture column of the vlt benchmarks;
  • it composes with the packument-prefetch work and the up-to-date short-circuit, so all three need to land before the vlt average reflects the wins.

Related


Written by an agent (Claude Code, claude-opus-4-7).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions