KhảiandClaude 815e507d67 ci(integrated-benchmark): scenarios without lockfiles (#11838)
* ci(benchmark): run all six integrated-benchmark scenarios

Wires `clean-install`, `full-resolution`, `peek`, and `gvs-warm` into
`pacquet-integrated-benchmark.yml` so per-PR runs cover the same scenario
set the manual `benchmark.yml` workflow already exercises via
`benchmarks/bench.sh`. Requested for #11837, where the perf delta affects
the resolution-bound scenarios (`firstInstall`, `withWarmCache`,
`withWarmModules`, `updatedDependencies`) that the prior two-scenario set
did not measure.

Each scenario gets its own step with a 10 min hyperfine timeout (same
rationale as the existing steps) and writes per-scenario report copies
that the summary step concatenates into `SUMMARY.md`.

* ci(benchmark): drop peek and gvs-warm scenarios

Keep only the two new no-lockfile scenarios (`clean-install`,
`full-resolution`) on top of the existing `frozen-lockfile` and
`frozen-lockfile-hot-cache`. #11837's perf change is in the
fresh-lockfile install path, which only runs when resolution runs — i.e.,
exactly the no-lockfile scenarios. `peek` mutates an existing lockfile
and `gvs-warm` is a frozen-lockfile variant; neither exercises the
affected path, and including them only costs per-PR CI wall time.

* fix(bench): pin packages: ['.'] in synthesized pnpm-workspace.yaml

The integrated-benchmark clones each pacquet revision's source tree into
`<bench_dir>/pacquet/`, which on the pnpm/pnpm monorepo includes upstream
test fixtures like
`workspace/project-manifest-reader/__fixtures__/invalid-package-json/package.json`
— intentionally malformed JSON used to exercise pnpm's manifest reader.

Without a `packages:` field, both pnpm's `findPackages.ts:28` and
pacquet's `crates/workspace/src/projects.rs:128` default to `[".", "**"]`,
so the fresh-resolve install path's `find_workspace_projects` walk
descends into the cloned source tree and trips on the bad fixture:

  Error: pacquet_package_manifest::serialization_error
    × installing dependencies
    ╰─▶ expected `,` or `}` at line 3 column 3

The walk only runs on the fresh-lockfile branch (`install.rs:628-630`),
which is why frozen-lockfile and frozen-lockfile-hot-cache stay green
while clean-install and full-resolution fail every time.

Pin `packages: ['.']` in the synthesized manifest so enumeration stays
at the workspace root. The benchmark's installs are single-project,
so this doesn't narrow anything the install actually needed to see.
Fixtures supplied via `--fixture-dir` that already declare `packages:`
keep their own value.

* ci(benchmark): bump no-lockfile scenarios to 20 min

Clean-install and full-resolution go through pacquet's fresh-resolve
install path, which is currently ~3-5x slower than pnpm on the
`alotta-files` fixture (pnpm/pnpm#11832). Hyperfine's default 1 warmup
+ 10 timed runs across three benchmark targets (pacquet@HEAD,
pacquet@main, system pnpm) projects to ~13 min wallclock for these
two scenarios, putting the previous 10 min cap right on the edge.
Doubling to 20 min keeps the per-step timeout meaningful as a stuck-
install detector without losing CI time when the bench is healthy.

The frozen-lockfile steps stay at 10 min — they don't traverse the
slower fresh-resolve path.

* fix(bench): drop --no-frozen-lockfile from full-resolution scenario

Pacquet doesn't expose `--no-frozen-lockfile` (only `--frozen-lockfile`,
`--prefer-frozen-lockfile`, and `--no-prefer-frozen-lockfile`). Passing
it makes clap reject the install:

  error: unexpected argument '--no-frozen-lockfile' found
    tip: a similar argument exists: '--frozen-lockfile'

The flag was redundant for this scenario anyway: full-resolution starts
every iteration with no lockfile on disk (init() skips the lockfile when
`lockfile_enabled()` is false; cleanup removes it; `lockfile=false` in
the synthesized npmrc/workspace prevents writing one). With no lockfile
present the frozen path is unreachable regardless of the flag, so both
tools take fresh resolution by definition. Fold full-resolution into
clean-install's bare `install` arm.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-22 08:03:51 +02:00
2026-04-10 18:30:33 +02:00
2026-04-10 18:30:33 +02:00
2026-05-20 12:41:09 +02:00
2026-05-20 16:51:13 +02:00
2026-05-20 12:41:09 +02:00
2026-05-21 15:45:17 +02:00
2026-05-20 16:51:13 +02:00
2026-05-20 12:41:09 +02:00
2026-05-20 16:51:13 +02:00
2026-05-20 12:41:09 +02:00
2026-04-30 23:03:46 +02:00
2026-05-21 15:45:17 +02:00
2026-05-20 16:51:13 +02:00
2026-05-21 15:45:17 +02:00
2026-05-20 12:41:09 +02:00
2026-05-20 12:41:09 +02:00
2026-05-20 16:51:13 +02:00
2026-05-20 12:41:09 +02:00
2026-05-20 12:41:09 +02:00
2026-05-20 12:41:09 +02:00
2026-05-21 15:45:17 +02:00
2026-05-21 15:45:17 +02:00
2026-05-21 15:45:17 +02:00
2026-05-20 16:51:13 +02:00
2026-04-30 23:19:31 +02:00
2026-05-20 16:51:13 +02:00
2026-05-20 16:51:13 +02:00
2026-04-30 23:03:46 +02:00
2026-05-20 12:41:09 +02:00
2026-05-20 16:51:13 +02:00
2026-01-16 16:31:31 +01:00
2024-03-21 01:09:22 +01:00
2022-06-01 02:48:58 +03:00

简体中文 | 日本語 | 한국어 | Italiano | Português Brasileiro

pnpm

Fast, disk space efficient package manager:

  • Fast. Up to 2x faster than the alternatives (see benchmark).
  • Efficient. Files inside node_modules are linked from a single content-addressable storage.
  • Great for monorepos.
  • Strict. A package can access only dependencies that are specified in its package.json.
  • Deterministic. Has a lockfile called pnpm-lock.yaml.
  • Works as a Node.js version manager. See pnpm runtime.
  • Works everywhere. Supports Windows, Linux, and macOS.
  • Battle-tested. Used in production by teams of all sizes since 2016.
  • See the full feature comparison with npm and Yarn.

To quote the Rush team:

Microsoft uses pnpm in Rush repos with hundreds of projects and hundreds of PRs per day, and we’ve found it to be very fast and reliable.

npm version OpenCollective OpenCollective X Follow Stand With Ukraine

Platinum Sponsors

Bit

Gold Sponsors

Sanity Discord Vite
SerpApi CodeRabbit Stackblitz
Workleap Nx

Silver Sponsors

Replit Cybozu devowl.io
u|screen Leniolabs_ Depot
Cerbos ⏱️ Time.now

Support this project by becoming a sponsor.

Background

pnpm uses a content-addressable filesystem to store all files from all module directories on a disk. When using npm, if you have 100 projects using lodash, you will have 100 copies of lodash on disk. With pnpm, lodash will be stored in a content-addressable storage, so:

  1. If you depend on different versions of lodash, only the files that differ are added to the store. If lodash has 100 files, and a new version has a change only in one of those files, pnpm update will only add 1 new file to the storage.
  2. All the files are saved in a single place on the disk. When packages are installed, their files are linked from that single place consuming no additional disk space. Linking is performed using either hard-links or reflinks (copy-on-write).

As a result, you save gigabytes of space on your disk and you have a lot faster installations! If you'd like more details about the unique node_modules structure that pnpm creates and why it works fine with the Node.js ecosystem, read this small article: Flat node_modules is not the only way.

💖 Like this project? Let people know with a tweet

Getting Started

Benchmark

pnpm is up to 2x faster than npm and Yarn classic. See all benchmarks here.

Benchmarks on an app with lots of dependencies:

License

MIT

S
Description
No description provided
Readme MIT
539 MiB
0 Stars 1 Watchers 0 Forks
Languages
Rust 68.2%
TypeScript 30.2%
JavaScript 1.4%
Shell 0.1%