graph_sequencer collected each topological chunk by rescanning every included node, so a graph whose chains produce as many chunks as nodes sorted in O(V * chunks) — with a full node hash (a PathBuf of the project directory) paid on every probe. A 6,833-project workspace whose projects each depend on their predecessors spent ~4 s per sort, and a plain install sorts twice (the recursive project selection and the workspace-cycle report), regressing pnpm:scope from 0.15 s to 4 s and pnpm:package-manifest from 0.5 s to 4.3 s between v12.0.0-rc.8 (which sorted nothing on a plain install) and rc.9 (where cfg.sort defaults the recursive sort on and pnpm/pnpm#14074 added the cycle check). Both implementations now intern the nodes to indices up front and gather each chunk from the nodes whose degree the previous chunk's removal dropped to zero, i.e. layered Kahn's in O(V log V + E) with no hashing in the loop. Chunk membership and order (following `included`), the cycle list, and the `safe` verdict are unchanged; the one divergence the rewrite removes is that the Rust port used to emit a node twice into one chunk when `included` listed it twice, where the TypeScript implementation deduplicated — both now deduplicate. The TypeScript graphSequencer had the same shape (its Map probes are cheaper, so it hid the cost longer) and is rewritten identically to keep the stacks aligned. On the pnpm/pnpm#14151 reproduction (6,833 projects), a warm no-op `pnpm install --lockfile-only` drops from 9.0 s (rc.9) to 1.7 s, and a one-dependency lockfile update from 14.2 s to 5.9 s — faster than Yarn 4's 7.2 s on the same change. The cycle pass is confined to strongly connected components (iterative Tarjan): nodes that merely lead into a cycle no longer pay a reachability walk each, and one ring's search cannot walk downstream rings. Reported cycles, chunk order, and the safe verdict are unchanged. The TypeScript side also appends cycle ids without a call-spread (argument-limit overflow on huge cycles) and replaces queue.shift() with a head index. A new workspace_sort micro-benchmark group covers the shape every existing benchmark missed (single-project integrated fixture; the workspace_resolution group starts downstream of sorting): the projects graph build plus sequencing over 4,000 chained projects — 538 ms quadratic, 15.7 ms now. Closes pnpm/pnpm#14149. Closes pnpm/pnpm#14151.
简体中文 | 日本語 | 한국어 | Italiano | Português Brasileiro
Fast, disk space efficient package manager:
- Fast. Up to 2x faster than the alternatives (see benchmark).
- Efficient. Files inside
node_modulesare 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.
- Experimental Rust port. Includes pacquet, an experimental port of the CLI written in Rust.
- 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.
Platinum Sponsors
|
|
|
|
Gold Sponsors
|
|
|
|
|
|
|
|
|
|
|
|
Silver Sponsors
|
|
|
|
|
|
|
|
|
|
|
| ⏱️ 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:
- 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 updatewill only add 1 new file to the storage. - 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, except the pnpr/ directory, which is source-available under the PolyForm Shield License 1.0.0.