Skip to content
Innovialabs

npm vs Yarn vs pnpm: Which Package Manager to Use

Practice3 min

In short

npm is the reliable default, pnpm saves disk space and enforces stricter dependencies, which shines in monorepos, and Yarn suits teams that want its special modes; above all, use one manager and one lockfile per project.

The short answer

  • npm ships with Node.js, nothing to install. It fits most projects.
  • pnpm keeps packages in a shared store and links them in: less disk space, fast reinstalls and strict access to dependencies. Great for monorepos.
  • Yarn (modern versions) offers Plug'n'Play mode without a node_modules folder and well-designed workspaces, but the team needs to understand its quirks.

More important than the choice itself: don't mix managers. A repository should have one lockfile.

The basics: package.json, semver and lockfiles

package.json describes the project: dependencies, scripts, Node.js version. Dependency versions follow semver — MAJOR.MINOR.PATCH:

  • ^1.4.2 — any 1.x.x from 1.4.2 up (new minor and patch versions);
  • ~1.4.2 — patches only, 1.4.x;
  • 1.4.2 — exactly this version.

A range means install can pick different versions today and a month from now. That is why a lockfile exists — it records exact versions of the whole dependency tree:

ManagerLockfile
npmpackage-lock.json
Yarnyarn.lock
pnpmpnpm-lock.yaml

Commit the lockfile. In CI, install strictly from it: npm ci, yarn install --immutable (modern Yarn), pnpm install --frozen-lockfile.

Comparing the three

CriterionnpmYarnpnpm
InstallationBundled with Node.jsVia Corepack or separatelyVia Corepack or separately
Disk usageA copy per projectDepends on modeShared store, links
StrictnessFlat node_modulesPnP is strictStrict by default
WorkspacesYesYes, matureYes, mature
CompatibilityHighestPnP sometimes needs setupHigh, rare packages need tweaks

Speed depends heavily on cache, network and project size, so compare on your own repository rather than trusting someone else's benchmarks.

What strictness means

npm creates a flat node_modules: your dependencies' dependencies sit at the top level, so code can import a package that is not in your package.json. That is a phantom dependency — it works until something higher up the tree drops it.

pnpm puts only direct dependencies at the root of node_modules; the rest are hidden. The bug shows up immediately instead of after an update. Yarn in PnP mode controls module resolution itself.

Workspaces and monorepos

All three support workspaces — several packages in one repo with a shared install. A pnpm example:

# pnpm-workspace.yaml
packages:
  - "apps/*"
  - "packages/*"

Internal packages are linked and there is a single lockfile. Large monorepos often pick pnpm for disk savings and strictness, while npm works fine for simplicity when there are only a few packages.

How to choose

  1. Small project or a team with no special needs — npm.
  2. Monorepo, many projects on one machine, strictness wanted — pnpm.
  3. Team already on Yarn and happy — stay; migrating for its own sake is not worth it.
  4. Pin the manager in the packageManager field of package.json and enable Corepack so everyone uses the same version.

Common mistakes

  • Two lockfiles in the repo — half the team installs one set of versions, half another.
  • Lockfile in .gitignore — builds stop being reproducible.
  • npm install instead of npm ci in CI — the lockfile can change silently.
  • Importing packages missing from package.json — works until the next update.

FAQ

Usually yes: pnpm can import an existing lockfile with pnpm import. Trouble appears when code relies on phantom dependencies — you will need to add them to package.json explicitly.

We can help with this

If you'd rather get the result than figure it all out yourself — this is what we do every day.

Discuss a project

Read next

Have an idea or a task? Tell us about it

We'll reply within one business day and propose a solution. The consultation is free.