# pnpm: one content-addressable store, three CLI trees, and a benchmark it does not print

> pnpm is a disk space efficient package manager whose CLI is being rewritten in Rust inside a repository that still carries its old pacquet name. The mechanism that makes it fast and small is also the one that breaks code which reaches for undeclared dependencies.

**pnpm/pnpm** — Fast, disk space efficient package manager

- Repository: https://github.com/pnpm/pnpm
- Website: https://pnpm.io
- Stars: 36,725 · Forks: 1,900
- Language: Rust
- License: MIT
- Published: 2026-08-17 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/pnpm-pnpm

## A single content-addressable store is what makes node_modules deduplicate

pnpm's central mechanism fits in one sentence: files inside `node_modules` are linked from a single content-addressable storage. The consequence is that a package stored once is reused by every project that asks for it, so a machine with many checkouts pays for one copy of a dependency instead of a copy per checkout. Resolution is pinned by `pnpm-lock.yaml`, and pnpm holds itself to the same rule while building pnpm, since the root justfile installs with

```bash
pnpm install --frozen-lockfile --prefer-offline
```

A contributor who edits a manifest without regenerating the lockfile gets a hard failure instead of a silent resolution change, and the prefer-offline flag makes a warm store the fast path. What that design does not tell you is what happens when a store entry goes missing or is corrupted partway through an install, because the README does not describe store recovery or a verify command. The top level of the tree does carry a DOCUMENTATION.md file, yet the README's own account of the store stops at the one sentence about linking. So the storage layout is the best documented part of the design and the failure modes of that same layout are the least documented, which is the wrong way round for the thing that touches every byte you install.

## The strict rule punishes any code that reaches up node_modules

pnpm states one rule that changes how JavaScript resolves dependencies: a package can access only dependencies that are specified in its `package.json`. Under a flat `node_modules`, a library that forgets to declare something often keeps working because some other package hoisted it into the same directory. Under this rule it does not. That is the intent, and it is also the bill. Any build plugin, test helper, or CLI shim that assumes it can reach an undeclared transitive dependency stops working, and the failure surfaces in your source file rather than in the install output, which sends people looking in the wrong place. The README does not name the configuration keys that loosen the layout, does not say which of them are safe in continuous integration, and does not list the tools known to need them. The repair path is therefore a documentation search on pnpm.io, not a line in the README. Note the tension between two headline claims: the monorepo bullet links to pnpm.io/workspaces, while the strictness bullet decides what each package inside a workspace can see. Plan for the second before you rely on the first.

## Three command line implementations share one repository, and the old name is still in the Cargo file

The tree holds `pnpm/`, `pnpm11/`, and `pnpr/` next to `pnpm-workspace.yaml`, and the Cargo workspace confirms the split with members `pnpm/crates/*`, `pnpm/tasks/*`, and `pnpr/crates/*`. Its dependency list names the moving parts one by one: `pnpm-cli`, `pnpm-matcher`, `pnpm-crypto-hash`, `pnpm-crypto-shasums-file`, `pnpm-env-installer`, `pnpm-env-replace`, `pnpm-fs`, `pnpm-fs-packlist`, `pnpm-cmd-shim`, `pnpm-auth-commands`, `pnpm-cargo-resolver`, a family of `pnpm-catalogs-*` crates, a `pnpr` client, and four engine resolvers covering yarn, node, bun, and deno. The naming has not caught up with the code. The README still calls the Rust port pacquet and labels it experimental, and the Cargo workspace description field reads `Pacquet` with a homepage of github.com/pnpm/pacquet. A newcomer searching for pacquet finds working code and inherits a name the project has moved beyond. The repository is MIT licensed, is not archived, and its last push is dated 2026-09-29, so the rename is in flight rather than settled. Version drift runs alongside it: the runtime link points at the 11.x documentation, the newest release listed is v12.8.2 from 2026-09-30, and v12.8.0 is tagged v12.8.0 while its package version reads pnpm 12.8.

## The 2x claim points at a benchmark the README does not print

The first bullet says pnpm is up to 2x faster than the alternatives, then hands the evidence to an anchor labelled benchmark. The README does not print that benchmark. There is no machine description, no Node version, no project shape, no indication of whether the measurement covers install only or install plus build, and no sample size behind the word up to. The qualifier is carrying the load a table would otherwise carry, so the headline is a ceiling rather than an expected result. A second piece of evidence arrives as a testimonial instead: the Rush team is quoted saying Microsoft uses pnpm in Rush repos with hundreds of projects and hundreds of PRs per day, and has found it very fast and reliable. That is a claim about one large deployment, not a number you can compare with your own repository. The sponsor tables add a third kind of signal, listing bit.cloud, openai, notion, and coderabbit as platinum sponsors and sanity, discord, vite.dev, serpapi, stackblitz, workleap, nx.dev, and latitude.so as gold. Every one of those links carries a `utm_source=pnpm` parameter, which is what funding looks like in a README. Run the install on your own tree before you repeat the speedup to anyone.

## Building the Rust CLI means binstalling eight tools and compiling a ninth from source

Working on the Rust side starts with the justfile `init` recipe, and the recipe is itself a description of the toolchain surface. It expects cargo-binstall to be present already, then installs the test runner, watcher, snapshot tester, spell checker, TOML formatter, and build tooling in one line:

```bash
cargo binstall cargo-nextest cargo-watch cargo-insta typos-cli taplo-cli wasm-pack cargo-llvm-cov sccache@0.17.0 -y
```

One tool cannot be fetched prebuilt, and the file says so, so it is installed from source at a locked version:

```bash
cargo install cargo-fixit@0.1.15 --locked
```

A formatting wrapper follows with `node pnpm/scripts/rustfmt.mjs --install`, and the package.json script `ready:rust` points at `just ready`. For a new contributor this means a source compile of a linting tool happens before you have read a line of package-manager logic, and the pinned sccache version shows that a stale global cache is a decision someone already had to make. The same discipline shows in the check and build steps, which refuse to move the lockfile and cover every target:

```bash
cargo check --locked --workspace --all-targets
```

The release binary itself is produced by `cargo build --release --bin pnpm`.

## just ready runs six steps and ends by printing your working tree

The default recipe lists recipes rather than building anything, running `just --list -u`, with `r`, `c`, and `t` aliased to ready, codecov, and test. The ready recipe is the clearest statement of the project's own quality bar, because its comment says it runs the same commands as continuous integration:

```bash
typos pnpm pnpr
node pnpm/scripts/rustfmt.mjs --all
just check
just test
just lint
git status
```

Six steps, and the last one hands control back to you by printing the working tree, so a formatter that rewrites files cannot make the run look clean. The typo check covers two source trees, pnpm and pnpr, while formatting and linting reach wider. The neighbouring recipes show where the edges are. `update` is `git pull` followed by `git submodule update --init`, with a comment saying it exists to sync the submodules, so a plain pull leaves the tree incomplete. The watch recipe needs a flag to route around a tool bug:

```bash
cargo watch --no-vcs-ignores -x '{{command}}'
```

The file explains that cargo-watch loads every .gitignore including the ones listed in .gitignore, hence the override. The test recipe also warns that a killed test process cannot run `TempDir` cleanup, so an interrupted run abandons its temporary directories, which is why the package.json scripts call `shx rm -rf ../pnpm_tmp` before the suites run.

## The README carries no install command, no Node floor, and no failure catalog

Adoption begins with a gap. There is no install command in the README, no curl line, no corepack invocation, and no stated minimum Node version, so the first action a new user takes is to leave for the website, where the workspaces guide, the feature comparison with npm and Yarn, and the runtime page live. What the file does carry is a self description as battle tested in production by teams of all sizes since 2016, a platform line for Windows, Linux, and macOS, a role as a Node.js version manager, and the Rush quotation reproduced as a brokered endorsement. None of that is a failure catalog. The README does not document what a failed install prints, does not document rollback, does not document store verification, does not document migrating an existing lockfile from another manager, and does not document what happens to a dependency that needs to run a build script after unpack. The package.json hints at how much of the real workflow lives elsewhere, with the test scripts comparing against origin/main through `git remote set-branches --add origin main` and filtering with `--filter=...[origin/main]`. Practical consequence: treat the README as a brochure and the documentation site as the manual, and rehearse any lockfile migration on a branch before a repository that has to keep building on Friday depends on it.

## Conclusion

Adopt pnpm when disk use across many checkouts and a lockfile-gated install matter more than the flat node_modules layout that some tooling assumes. Read pnpm.io/feature-comparison before moving a monorepo, measure the install on your own repository rather than quoting the 2x line, and confirm that nothing in your dependency tree reaches outside its own package.json.

## FAQ

### Is pnpm better than npm?

The README claims pnpm is up to 2x faster than the alternatives and links a feature comparison with npm and Yarn at pnpm.io/feature-comparison, but it does not print the benchmark table itself. Whether it suits you depends on whether linking node_modules from one content-addressable storage and the strict rule that a package sees only its own declared dependencies work for your code.

### What is the purpose of pnpm?

pnpm describes itself as a fast, disk space efficient package manager whose files inside node_modules are linked from a single content-addressable storage. It also works as a Node.js version manager, supports Windows, Linux, and macOS, and keeps resolution in a lockfile called pnpm-lock.yaml.

### What companies use pnpm?

The README quotes the Rush team saying Microsoft uses pnpm in Rush repos with hundreds of projects and hundreds of PRs per day. It also lists openai, notion, bit.cloud, vite.dev, discord, sanity, replit, and nx.dev among its sponsors, and every sponsor link carries a utm_source=pnpm parameter, so sponsorship and adoption are separate signals.

### How to use the pnpm?

The README itself carries no install command and no Node version requirement, so setup happens on the documentation site at pnpm.io, where the workspaces guide and the runtime page live. Inside the repository the entry points are the justfile recipes and the package.json scripts, including pnpm install --frozen-lockfile --prefer-offline and just ready.

### pnpm 10 vs pnpm 11

The repository keeps a pnpm11/ directory and the README's runtime link points at the 11.x documentation, while the newest release listed is v12.8.2 from 2026-09-30, with v12.8.1 and v12.8.0 both dated 2026-09-28. The README does not describe what changed between those major versions, so the version-specific behavior has to come from the documentation site.

## Sources

- [Official documentation](https://pnpm.io)
- [Official README](https://github.com/pnpm/pnpm#readme)
- [Project repository](https://github.com/pnpm/pnpm)
- [Release notes](https://github.com/pnpm/pnpm/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pnpm-pnpm
