Resolution re-derived the same data once per dependency edge instead of once per packument: - filterPkgMetadataByPublishDate ran on every pick (every edge) with minimumReleaseAge active — the default since it is 1440 min — parsing a Date per version and rebuilding the versions map each time. It is now memoized per packument object in a WeakMap, keyed by cutoff and trusted versions so one packument served under different policies still filters per policy. Sharing the returned object is safe: callers already shared the inner version manifests, and the packument objects the resolver passes in are themselves cached and treated as read-only. - pickPackageFromMeta re-parsed version strings and ranges on every satisfies/maxSatisfying call. Parsed SemVer and Range instances are now cached in capped Maps (cleared at 50k entries so long-lived processes cannot grow them without bound), and maxSatisfying/ minSatisfying are replaced with loops that reuse the caches. The dist-tag repopulation loop in the publish-date filter likewise compares already-parsed instances instead of calling semver.gt on strings. - Concurrent offline picks of one package all miss the pre-queue in-memory cache check, then each re-read and re-parsed the mirror behind the per-package limiter (176 of 1311 loads on the benchmark fixture were duplicates). The limiter callback now re-checks the cache; offline entries are always disk-sourced, so this is equivalent to arriving after the first caller cached it. - clearMeta condensed every version object through ramda's curried pick; a direct field loop does the same with no per-field dispatch. The presence check via undefined-comparison matches the previous behavior because version objects come from JSON, which cannot encode undefined. Resolution of the 1246-package benchmark fixture is 12.5% faster on top of current main (4.27s -> 3.73s, hyperfine, offline hot cache); the resulting lockfile is byte-identical. Attribution: filter memoization -11%, semver caches -4%, the rest ~-1%.
pacquet
Warning
pacquet is under active development and not yet ready for production use.
The official pnpm rewrite in Rust.
pacquet is the pnpm CLI implemented in Rust — one of two parallel implementations of the same package manager, kept behaviorally identical (the same commands, flags, defaults, error codes, file formats, and directory layout). It is developed alongside the TypeScript pnpm CLI at near-complete feature parity, not as a downstream port that trails it.
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.