Best JavaScript Package Managers in 2026: npm vs pnpm vs Yarn
·PkgPulse Team
TL;DR
pnpm for monorepos and disk efficiency; npm for simplicity; Yarn Berry for Plug'n'Play. pnpm (~12M weekly downloads) uses a content-addressable store — install each package version once on your machine, hard-link everywhere. npm (~100M+ is built into Node.js, used everywhere. Yarn Berry (~6M downloads) with PnP eliminates node_modules entirely but has ecosystem compatibility issues. For new projects in 2026, pnpm is the technical winner; npm is the safe default.
Key Takeaways
- npm: ~100M+ downloads — built into Node.js, largest ecosystem, default for most
- pnpm: ~12M downloads — 2x faster installs, 70% less disk space, strictest resolution
- Yarn Berry: ~6M downloads — PnP mode eliminates node_modules; workspace support
- Bun: ~2M downloads — 3-5x faster than npm, all-in-one runtime+bundler+pm
- pnpm workspaces — best-in-class monorepo support with workspace protocol
npm (The Standard)
# npm — built into Node.js, no install needed
npm install react react-dom
npm install -D typescript @types/react
# Workspaces
npm install --workspace=apps/web react
npm run build --workspace=apps/web
# Common flags
npm install --legacy-peer-deps # Fix peer dep conflicts
npm ci # Clean install from lockfile (CI)
npm audit # Security audit
npm outdated # List outdated packages
npm update # Update within semver ranges
// package.json — npm workspaces
{
"workspaces": ["apps/*", "packages/*"],
"scripts": {
"build": "npm run build --workspaces --if-present",
"test": "npm test --workspaces --if-present"
}
}
# npm lockfile — package-lock.json
# Always commit this file! It ensures reproducible installs.
# If you see conflicts, resolve by running npm install locally.
# npm 7+ — automatic peer deps install
# npm 8+ — workspaces --if-present flag
# npm 9+ -- better provenance and audit features
# npm 10+ -- improved caching, workspace improvements
pnpm (Recommended)
# Install pnpm
npm install -g pnpm
# or: curl -fsSL https://get.pnpm.io/install.sh | sh -
# pnpm commands (same API as npm)
pnpm install
pnpm add react react-dom
pnpm add -D typescript
pnpm remove lodash
# The magic: content-addressable store
# ~/.pnpm-store — packages stored ONCE, hard-linked
# node_modules/.pnpm — virtual store with flat deps
# pnpm-workspace.yaml — monorepo config
packages:
- 'apps/*'
- 'packages/*'
- '!**/test/**'
# pnpm workspace commands
pnpm --filter web install # Install deps for web only
pnpm --filter web build # Build web package
pnpm --filter '...web' build # Build web and its deps
pnpm --filter './packages/**' test # Test all packages
pnpm -r build # Recursive: build all
# pnpm workspace protocol
# In apps/web/package.json:
# "dependencies": { "@myrepo/ui": "workspace:*" }
# This links to the local package — no version pinning needed
# pnpm performance vs npm
# Fresh install (200 packages):
# npm: 45s
# pnpm: 22s (2x faster, ~70% less disk)
# yarn: 30s
# Cached install:
# npm: 15s
# pnpm: 5s (3x faster)
# yarn: 8s
# .npmrc — pnpm strict mode (prevents phantom dependencies)
shamefully-hoist=false # Don't hoist transitive deps to root
strict-peer-dependencies=true # Fail on peer dep conflicts
Yarn Berry (PnP)
# Yarn Berry — enable in project
yarn set version stable # Switch to Yarn Berry
# or: yarn set version berry
# .yarnrc.yml — created automatically
# .yarnrc.yml — Yarn Berry config
nodeLinker: pnp # Plug'n'Play (no node_modules)
# nodeLinker: node-modules # Traditional (if PnP compatibility issues)
yarnPath: .yarn/releases/yarn-4.x.y.cjs
# Yarn Berry PnP — key difference
# PnP: No node_modules! Uses .pnp.cjs for module resolution
# Benefit: 70% faster cold installs, zero phantom deps
# Problem: ~15% of packages are PnP-incompatible (check compatibility)
# Check if a package works with PnP:
yarn dlx @yarnpkg/doctor
# Common PnP issues:
# 1. require('some-package') in scripts (use 'import' instead)
# 2. Packages using __dirname in non-standard ways
# 3. Some native addons
# If PnP breaks too many things:
# nodeLinker: node-modules # Fall back to traditional
# Yarn Berry workspaces
yarn workspaces list
yarn workspace web add react
yarn workspaces foreach run build
yarn workspace @myrepo/ui test
Bun (Speed Demon)
# Bun — all-in-one: runtime + bundler + package manager
curl -fsSL https://bun.sh/install | bash
# bun install — 3-5x faster than npm
bun install
bun add react react-dom
bun remove lodash
# Bun uses npm registry — fully compatible
# bun.lockb — binary lockfile (fast to read, not human-readable)
# Run scripts with bun runtime
bun run start # Much faster than: node server.js
bun run dev # ts files work natively, no transpile step
bun test # Built-in test runner (Jest-compatible)
Installation Speed Benchmark
| Package Manager | Cold Install | Warm Install | Disk Space |
|---|---|---|---|
| Bun | ~8s | ~1s | Medium |
| pnpm | ~22s | ~5s | Minimal (shared store) |
| Yarn Berry (PnP) | ~15s | ~3s | Minimal |
| Yarn Berry (nm) | ~28s | ~8s | Medium |
| npm | ~45s | ~15s | Large |
Benchmarks for create-react-app style project (~200 deps). Your numbers will vary.
When to Choose
| Scenario | Pick |
|---|---|
| New project, no specific needs | pnpm |
| Monorepo with many packages | pnpm (workspace: protocol) |
| CI/CD speed is critical | pnpm or Bun |
| Disk space is limited | pnpm (shared store) |
| Zero-compromise compatibility | npm |
| Bun-native project | Bun |
| Already using Yarn, migrating | Yarn Berry (with node-modules linker) |
| Zero node_modules (advanced) | Yarn Berry PnP |
| Corporate environment, no choices | npm |
Compare package manager stats on PkgPulse.
See the live comparison
View npm vs. pnpm on PkgPulse →