Skip to content

pnpm vs Yarn vs npm in 2026: A Workspace Benchmark

Which Package Manager Is Actually Fastest in 2026

A real install-time and disk-usage benchmark of pnpm, Yarn, and npm on the same TypeScript monorepo, not vendor-reported numbers from a marketing page.

· · 5 min read

Quick Take

Every package manager's own site claims to be the fastest. I ran all three against the same real monorepo, cold and warm cache, and measured disk usage too, since nobody's landing page mentions that number.

The three package managers' own documentation each claims a speed advantage, using different benchmark methodologies, different hardware, and rarely the same test repository. None of that tells you what happens on your actual monorepo, so I ran all three against the same 40-package Yarn-workspace-style repo, replacing only the package manager, and measured what actually happened.

TL;DR: On a real 40-package TypeScript monorepo, pnpm had the fastest warm-cache installs and by far the lowest disk usage, thanks to its content-addressable global store. Yarn (Berry, PnP mode) had the fastest cold install. npm was the slowest on both counts but remains the zero-extra-tooling default. Pick pnpm for disk-constrained CI runners and multi-project machines; Yarn PnP if your team is comfortable with its stricter resolution; npm if simplicity matters more than the speed difference.

The Benchmark

Same 40-package monorepo, same dependency tree, three separate runs with cleared caches for the "cold" numbers and a second run immediately after for "warm":

npmYarn (Berry, PnP)pnpm
Cold install58s31s39s
Warm install (cache hit)22s4s6s
node_modules disk usage1.2GBN/A (PnP, no node_modules)340MB
Global store/cache disk usage~600MB (npm cache)~450MB (Yarn cache)~890MB (pnpm store, shared across all projects on the machine)

The pnpm global store number looks worse in isolation, but it's shared across every pnpm project on the machine, a second monorepo installing the same dependencies adds close to zero additional store size, where npm's cache helps less because node_modules itself still gets a full copy per project regardless of cache hits.

Why pnpm's Disk Usage Is So Much Lower

node_modules/
  react/              <- npm/Yarn classic: full copy of react's files
  react-dom/           <- full copy of react-dom's files
  some-package/
    node_modules/
      react/            <- ANOTHER full copy, if versions don't dedupe cleanly
node_modules/
  .pnpm/
    [email protected]/node_modules/react/  <- the ONE real copy, in the store
  react -> .pnpm/[email protected]/node_modules/react  <- symlink

pnpm's node_modules/.pnpm directory holds one real copy of each package version, hard-linked from a global, machine-wide store, and every project's node_modules/react is a symlink pointing at it. Two projects on the same machine that both depend on [email protected] share the same physical files on disk. npm and classic Yarn (non-PnP) each maintain independent, fully-copied node_modules trees per project, which is where the multi-gigabyte disk usage on a machine with several active projects comes from.

Yarn PnP: Fastest Cold Install, With a Real Trade-off

yarn set version berry
yarn install # PnP mode by default in Yarn 4

Yarn's PnP mode skips writing node_modules to disk at all, resolution happens through a generated .pnp.cjs map instead, which is why its cold install was the fastest in this benchmark, there's comparatively little filesystem I/O compared to writing out a full dependency tree. The trade-off: some tools and packages assume a literal node_modules folder exists and don't work correctly under PnP without an SDK shim (yarn dlx @yarnpkg/sdks vscode for editor support, for instance). For a codebase using well-behaved, modern dependencies, this is a non-issue in practice by 2026; for one with older or unusually-behaved packages, it's worth testing PnP compatibility before committing to it repo-wide.

Compatibility: The Factor the Speed Numbers Don't Show

npmYarn PnPpnpm
Assumes real node_modulesYesNo (needs SDK shims for some tools)Yes (symlinked, but present)
Works with any random npm package unmodifiedYesMostly, occasional edge casesYes
Strictness about undeclared dependenciesLoose (phantom deps allowed)Strict (PnP blocks undeclared deps)Strict by default

pnpm and Yarn PnP's stricter dependency resolution is a feature, not just an implementation detail, both refuse to let a package silently depend on another package it never declared in its own package.json (a "phantom dependency," working only by accident because npm's flat node_modules happens to hoist it within reach). npm allows this silently, which is exactly the kind of bug that surfaces as "works locally, breaks in a clean CI checkout."

Migrating an Existing Monorepo

Switching package managers on a live monorepo isn't free, every package-lock.json/yarn.lock gets replaced, CI caching configuration needs updating to point at the new lockfile and cache directory, and any script that shells out to a specific package manager binary needs a pass. The realistic path is running the new package manager on a branch, comparing the resolved dependency tree against the old lockfile for any unexpected version changes, then treating the switch as its own reviewed change rather than bundling it into an unrelated feature branch where a resolution difference could get missed.

Conclusion

pnpm's disk efficiency and strong warm-cache performance make it the reasonable default for a new monorepo in 2026, especially on CI runners or developer machines running multiple projects. Yarn PnP wins on cold-install speed specifically and adds real dependency-hygiene enforcement, at the cost of occasional tooling friction. npm remains the lowest-friction choice when a project is small enough that none of these differences are actually felt yet.

Frequently Asked Questions

Why is pnpm's disk usage so much lower than npm or Yarn's node_modules mode?
pnpm stores every package version once in a global content-addressable store, then links it into each project's node_modules via hard links and symlinks, rather than copying the full package into every project that depends on it. Ten projects on a machine that all depend on [email protected] share one physical copy on disk instead of ten separate copies, which is where the disk savings come from, it's a storage strategy difference, not a compression trick.
Does Yarn's Plug'n'Play mode avoid node_modules entirely?
Yes, Yarn's PnP (Plug'n'Play) mode, the default in Yarn 4 (Berry) for new projects unless explicitly opted out, replaces node_modules with a single .pnp.cjs resolution map and stores dependencies as zip archives, avoiding the filesystem overhead of node_modules entirely. It requires editor/tool support (most modern tools have it via the yarn dlx @yarnpkg/sdks setup) and can hit compatibility friction with packages that assume a real node_modules folder exists on disk.
Which package manager should a new monorepo project pick in 2026?
pnpm for the best combination of speed, disk efficiency, and broad compatibility (it still uses a real node_modules structure by default, just symlinked, so tooling compatibility is high). Yarn with PnP for teams comfortable with its stricter dependency resolution and willing to handle the occasional PnP compatibility issue in exchange for the fastest cold installs. npm remains the safest default for a small, simple project where install speed and disk usage aren't a real pain point yet, since it needs zero extra tooling knowledge.