Overview
Use pnpm for new projects. It installs faster than Yarn on most machines, uses a content-addressable store that saves gigabytes across projects, and enforces strict dependency isolation so phantom dependencies cause build errors rather than silent runtime bugs. Use Yarn Berry (v4) only when Plug’n’Play mode, Yarn’s constraint engine, or its specific protocol handlers (portal:, patch:) are genuine requirements on the project. See migrate-from-npm-to-pnpm for the migration steps.
When pnpm wins
pnpm is the default for most new projects and monorepos.
- Disk efficiency: pnpm uses a global content-addressable store. Every version of every package is stored once on disk and hard-linked into each project’s
node_modules. A machine running 20 Node projects typically saves 5 to 15 GB compared to npm or Yarn. - Speed: install times are 30 to 50 percent faster than
npm installand comparable to Yarn on cache hits. The store means cold installs on a new machine reuse packages from other projects. - Strict isolation: pnpm does not hoist all packages to the top-level
node_modules. A package can only import what it declares in its ownpackage.json. Phantom dependency bugs surface during install, not in production. - Monorepo workspaces:
pnpm-workspace.yamlis simple and well-understood.pnpm -r run buildruns a command in all workspace packages in topological order. - Compatibility: pnpm is compatible with
package.jsonand the npm registry. CI environments support it viaactions/setup-nodewithcache: pnpm.
# pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"When Yarn wins
Yarn Berry (v4) wins in specific cases.
- Plug’n’Play (PnP) mode: Yarn PnP eliminates
node_modulesentirely, replacing it with a.pnp.cjsloader. Build times drop and the install is reproducible withoutnode_modulesin the repo. The constraint is that every package in the dependency graph must be PnP-compatible. Some native modules and older packages are not. patch:protocol: Yarn’spatch:resolution lets you patch an upstream package inline with a diff checked into the repo, without forking the package. pnpm haspnpm patchwhich is similar but Yarn’s is more mature.- Constraint engine: Yarn’s constraint system enforces workspace-level rules (consistent dependency versions across packages) using a Prolog-like DSL. pnpm has
syncpackas an external alternative. - Existing Yarn v1 codebase committed to Berry upgrade: incremental migration within the Yarn ecosystem.
Trade-offs at a glance
| Dimension | pnpm | Yarn Berry (v4) |
|---|---|---|
| Disk usage | Low (global content store) | Very low with PnP; standard with node-modules linker |
| Install speed | Fast | Fast; fastest with PnP and zero-installs |
| Phantom dependency safety | Strict isolation by default | PnP catches them; node-modules linker does not |
| Monorepo workspaces | pnpm-workspace.yaml | workspaces in package.json |
| PnP support | No | First-class |
| Patch protocol | pnpm patch (file-based) | patch: in resolutions (diff-based) |
| Constraint engine | External tools (syncpack) | Built-in Prolog DSL |
| CI cache setup | Standard via actions/setup-node | Requires .yarn/cache config |
| Compatibility | High; works with most packages | PnP has friction with non-compliant packages |
| Community traction | Growing; default in many starters | Stable; Meta, large monorepos |
Migration cost
npm or Yarn v1 to pnpm is typically low-effort.
- Remove
node_modulesandyarn.lockorpackage-lock.json. - Run
pnpm importto generatepnpm-lock.yamlfrom the existing lock file. - Replace
npm runoryarncalls in CI and scripts withpnpm. - Fix any phantom dependency issues that surface. These are real bugs; fixing them is a feature.
- Effort: half a day for a single-package project; one to two days for a monorepo with many packages.
See migrate-from-npm-to-pnpm for the step-by-step.
Recommendation
- New project: pnpm.
- New monorepo: pnpm with
pnpm-workspace.yaml. Pair with Turborepo for caching; see turborepo-vs-nx. - Existing Yarn v1 project: migrate to pnpm. Yarn v1 is in maintenance mode.
- Existing Yarn Berry project with PnP working: stay; the migration cost is not justified.
- CI: enable pnpm store caching from day one to make remote installs fast.