Back to JavaScript
JavaScript
medium
mid

What is the difference between npm and yarn?

Both are package managers for the npm registry. Yarn originally fixed npm's speed, lockfile, and determinism gaps; npm has since caught up (package-lock, npm ci, workspaces). Today differences are small — Yarn Berry adds PnP/zero-installs; pnpm is the notable alternative with a content-addressed store.

4 min read·~5 min to think through

npm and Yarn both install JavaScript packages from the same npm registry — they differ in implementation, speed, and features. The honest answer is that the gap has largely closed.

The history (why Yarn exists)

When Yarn launched (2016), npm had real problems: slow installs, non-deterministic node_modules (no lockfile by default), and no offline cache. Yarn fixed all three — yarn.lock, parallel installs, a local cache, deterministic trees.

npm caught up

npm responded: package-lock.json for determinism, npm ci for fast, clean, lockfile-exact installs in CI, a cache, and workspaces for monorepos. For everyday use, modern npm and Yarn Classic are very close.

Where they differ today

  • Lockfilepackage-lock.json vs yarn.lock (don't commit both; pick one per repo).
  • Commands — minor differences (npm install vs yarn add, npm run x vs yarn x).
  • Yarn Berry (v2+) — bigger departure: Plug'n'Play (no node_modules folder, faster, stricter), zero-installs, and a plugin system. More setup friction; not all tools support PnP cleanly.
  • npm is the default — ships with Node, no extra install, ubiquitous.

pnpm — the one actually worth mentioning

The notable modern alternative: pnpm uses a content-addressed global store and hard-links packages into node_modules, so each package is stored once on disk across all projects. It's fast, disk-efficient, and has a stricter, non-flat node_modules that prevents "phantom dependency" bugs. Many teams have moved npm/Yarn → pnpm.

What actually matters

Pick one per project and commit its lockfile. Consistency (everyone and CI using the same manager + lockfile) matters far more than which one. Don't mix lockfiles.

The framing

"Both install from the same registry. Yarn originally fixed npm's speed, determinism, and lockfile gaps — but npm caught up with package-lock.json, npm ci, and workspaces, so for normal use they're close. The real differentiators today are Yarn Berry's Plug'n'Play and pnpm's content-addressed store, which is fast and disk-efficient and what a lot of teams have moved to. Practically: pick one per repo, commit its lockfile, and be consistent."

Follow-up questions

  • What does `npm ci` do differently from `npm install`?
  • How does pnpm save disk space?
  • What is Yarn's Plug'n'Play and what does it trade off?
  • Why shouldn't you commit both package-lock.json and yarn.lock?

Common mistakes

  • Claiming Yarn is still dramatically faster — npm has largely caught up.
  • Committing both lockfiles in the same repo.
  • Mixing npm and yarn commands in one project.
  • Not knowing pnpm exists / why teams adopt it.

Performance considerations

  • Install speed and disk usage are the differentiators: pnpm's hard-linked store is fastest and most disk-efficient; npm ci and Yarn are comparable for typical projects. CI cache configuration usually matters more than the manager choice.

Edge cases

  • CI installs — use npm ci / yarn --frozen-lockfile for reproducibility.
  • Monorepos — workspaces behavior differs slightly across managers.
  • Yarn PnP breaking tools that expect a node_modules folder.

Real-world examples

  • Teams standardizing on pnpm for monorepos to cut install time and disk use.
  • CI pipelines using npm ci for deterministic, lockfile-exact installs.

Senior engineer discussion

Seniors give the historical context, acknowledge npm closed the gap, highlight pnpm's content-addressed store and Yarn Berry's PnP as the real modern distinctions, and stress that per-repo consistency and committing the lockfile matter more than the brand.

Related questions