Frontend Development › Frontend Build Tooling
npm vs pnpm vs Yarn
JavaScript package managers and their trade-offs.
Also known as: npm vs pnpm vs yarn, package managers, pnpm
npm, pnpm and Yarn install the same registry packages with different storage models: npm nests then hoists (flat-ish tree, phantom-dependency risks), Yarn Berry adds Plug’n’Play (no node_modules, strict resolution), pnpm uses content-addressable symlinks (one copy on disk, strict by default — phantom imports fail loudly).
npm: node_modules with hoisting (lenient, occasionally phantom)
pnpm: symlinked store, strict (undeclared imports error)
yarn: classic hoist or PnP (strict, zero-install capable)
Strictness is the real divide: pnpm/Yarn-PnP surface missing declarations immediately; npm tolerates them until a clean install or different order breaks. Speed and disk follow (pnpm’s shared store wins monorepos), but correctness culture matters more than minutes.
The classic mistakes:
- Phantom dependencies. Importing packages you never declared works under hoisting — until it doesn’t (fresh CI, different manager, version drifts). Strict managers or lint rules (
eslint-plugin-importno-extraneous) catch it. - Lockfile neglect. Uncommitted or merge-corrupted lockfiles make installs non-reproducible. Commit lockfiles; regenerate deliberately; resolve conflicts by regenerating, not hand-editing.
- Manager mixing. npm and pnpm lockfiles in one repo (teammates using different clients) diverge dependency trees silently. One manager per repo, enforced (packageManager field, engine checks).
- Postinstall blindness. Install scripts execute arbitrary code — the supply-chain’s front door. Audit new deps’ scripts; restrict with
--ignore-scriptswhere feasible. - Global installs for projects. Global CLIs drift per machine; project-local devDependencies (run via scripts) pin the toolchain per repo.
- Cache confusion. Debugging installs by deleting caches ritualistically wastes hours;
--frozen-lockfileCI installs plus cleannode_modulesreinstalls resolve most states. - Ignoring audit signals. Vulnerability reports need triage cadence, not panic or apathy. Fold audits into the update routine.
How to choose: strictness and monorepo fit argue pnpm; ecosystem default argues npm; advanced workflows argue Yarn Berry. All three work — pick one per repo and enforce it.