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 install and 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 own package.json. Phantom dependency bugs surface during install, not in production.
  • Monorepo workspaces: pnpm-workspace.yaml is simple and well-understood. pnpm -r run build runs a command in all workspace packages in topological order.
  • Compatibility: pnpm is compatible with package.json and the npm registry. CI environments support it via actions/setup-node with cache: 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_modules entirely, replacing it with a .pnp.cjs loader. Build times drop and the install is reproducible without node_modules in 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’s patch: resolution lets you patch an upstream package inline with a diff checked into the repo, without forking the package. pnpm has pnpm patch which 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 syncpack as an external alternative.
  • Existing Yarn v1 codebase committed to Berry upgrade: incremental migration within the Yarn ecosystem.

Trade-offs at a glance

DimensionpnpmYarn Berry (v4)
Disk usageLow (global content store)Very low with PnP; standard with node-modules linker
Install speedFastFast; fastest with PnP and zero-installs
Phantom dependency safetyStrict isolation by defaultPnP catches them; node-modules linker does not
Monorepo workspacespnpm-workspace.yamlworkspaces in package.json
PnP supportNoFirst-class
Patch protocolpnpm patch (file-based)patch: in resolutions (diff-based)
Constraint engineExternal tools (syncpack)Built-in Prolog DSL
CI cache setupStandard via actions/setup-nodeRequires .yarn/cache config
CompatibilityHigh; works with most packagesPnP has friction with non-compliant packages
Community tractionGrowing; default in many startersStable; Meta, large monorepos

Migration cost

npm or Yarn v1 to pnpm is typically low-effort.

  • Remove node_modules and yarn.lock or package-lock.json.
  • Run pnpm import to generate pnpm-lock.yaml from the existing lock file.
  • Replace npm run or yarn calls in CI and scripts with pnpm.
  • 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.