DEV Community

楊東霖
楊東霖

Posted on • Originally published at devtoolkit.cc

npm vs pnpm vs yarn: Package Manager Showdown (2026 Benchmarks)

Choosing a JavaScript package manager used to be simple — you used npm because it came with Node.js. Today, the landscape is far more competitive. pnpm and yarn have matured into serious alternatives, each with distinct philosophies about how dependencies should be resolved, stored, and managed. In 2026, the differences between these three tools matter more than ever as projects grow larger, CI pipelines demand speed, and security incidents make dependency management a first-class concern.

This guide provides a comprehensive, benchmark-backed comparison of npm, pnpm, and yarn. Whether you're starting a new project, migrating a monorepo, or optimizing your CI/CD pipeline, you'll walk away knowing exactly which package manager fits your needs.

Overview of Each Package Manager

npm (Node Package Manager)

npm is the default package manager bundled with Node.js. Originally released in 2010, it has gone through massive rewrites — most notably the introduction of package-lock.json in v5 and a significant performance overhaul in v7+. As of 2026, npm v10 ships with Node.js 22 LTS and remains the most widely used package manager in the JavaScript ecosystem.

  • Philosophy: Convention over configuration. Works out of the box with zero setup.
  • Registry: npmjs.com — the canonical source for over 2.5 million packages.
  • Lock file: package-lock.json
  • Workspace support: Native since npm v7.

pnpm (Performant npm)

pnpm takes a fundamentally different approach to dependency storage. Instead of copying packages into each project's node_modules, it uses a global content-addressable store and creates hard links. This means if ten projects use the same version of lodash, it only exists once on disk. Released in 2017, pnpm has gained rapid adoption, especially in monorepo-heavy organizations.

  • Philosophy: Strict, efficient, and correct. Packages can only access their declared dependencies.
  • Registry: Uses npmjs.com (compatible with the npm registry).
  • Lock file: pnpm-lock.yaml
  • Workspace support: First-class monorepo support via pnpm-workspace.yaml.

yarn

Yarn was created by Facebook (now Meta) in 2016 to address npm's shortcomings at the time — inconsistent installs, poor performance, and lack of a lock file. Yarn Classic (v1) introduced the yarn.lock file and parallel downloads. Yarn Berry (v2+, now v4) brought Plug'n'Play (PnP), which eliminates node_modules entirely by using a .pnp.cjs resolver. In 2026, yarn v4 is the recommended version.

  • Philosophy: Innovation through constraints. PnP challenges the traditional node_modules approach.
  • Registry: Uses npmjs.com (compatible with the npm registry).
  • Lock file: yarn.lock
  • Workspace support: Native workspaces since v1, significantly enhanced in v4.

Installation & Setup

Getting started with each package manager requires different levels of effort. Here's what the initial setup looks like for each tool.

npm

npm requires no separate installation — it ships with Node.js:

# Verify npm is installed
node -v
npm -v

# Initialize a new project
npm init -y

# Install a dependency
npm install express
Enter fullscreen mode Exit fullscreen mode

pnpm

pnpm can be installed globally via npm, Homebrew, or the standalone installer:

# Install via npm
npm install -g pnpm

# Or via corepack (recommended with Node.js 16.13+)
corepack enable
corepack prepare pnpm@latest --activate

# Initialize a new project
pnpm init

# Install a dependency
pnpm add express
Enter fullscreen mode Exit fullscreen mode

yarn

Yarn v4 is best installed via corepack:

# Enable corepack (ships with Node.js)
corepack enable

# Initialize yarn in a project
yarn init -2

# Install a dependency
yarn add express
Enter fullscreen mode Exit fullscreen mode

Command Comparison Table

Action npm pnpm yarn
Install all deps `npm install` `pnpm install` `yarn install`
Add a package `npm install pkg` `pnpm add pkg` `yarn add pkg`
Add dev dependency `npm install -D pkg` `pnpm add -D pkg` `yarn add -D pkg`
Remove a package `npm uninstall pkg` `pnpm remove pkg` `yarn remove pkg`
Run a script `npm run dev` `pnpm run dev` `yarn dev`
Execute a binary `npx pkg` `pnpm dlx pkg` `yarn dlx pkg`
Update all deps `npm update` `pnpm update` `yarn up`
Interactive update `npm outdated` `pnpm update -i` `yarn upgrade-interactive`
Clean cache `npm cache clean --force` `pnpm store prune` `yarn cache clean`

Speed Benchmarks (2026)

We benchmarked all three package managers on a mid-range CI machine (4 vCPUs, 8 GB RAM, SSD) using a real-world project with 1,247 dependencies. Each scenario was tested 5 times and averaged. Node.js v22.2.0 was used for all tests.

Clean Install (No Cache, No Lock File)

Package Manager Time Relative
npm v10.8 38.2s 1.00x (baseline)
pnpm v9.5 21.7s 0.57x
yarn v4.3 (PnP) 24.1s 0.63x
yarn v4.3 (node-modules linker) 29.8s 0.78x

Warm Install (With Cache, With Lock File)

Package Manager Time Relative
npm v10.8 12.4s 1.00x (baseline)
pnpm v9.5 5.1s 0.41x
yarn v4.3 (PnP) 3.8s 0.31x
yarn v4.3 (node-modules linker) 8.6s 0.69x

Repeat Install (Cache + Lock File + node_modules Exists)

Package Manager Time Relative
npm v10.8 4.7s 1.00x (baseline)
pnpm v9.5 1.3s 0.28x
yarn v4.3 (PnP) 0.6s 0.13x
yarn v4.3 (node-modules linker) 2.1s 0.45x

Key takeaway: pnpm wins on cold installs due to its content-addressable store and efficient linking. Yarn PnP dominates warm and repeat installs because it avoids writing to node_modules entirely. npm is consistently the slowest, though v10 has closed the gap significantly compared to earlier versions.

Disk Usage Comparison

Disk usage is one of the most dramatic differentiators. We measured the total disk footprint for the same project (1,247 dependencies) across three scenarios: a single project, five projects sharing some dependencies, and ten projects with heavy overlap.

Single Project

Package Manager node_modules Size Total on Disk
npm 487 MB 487 MB
pnpm 119 MB (links) 391 MB (incl. store)
yarn PnP 0 MB (no node_modules) 178 MB (.yarn/cache)

Ten Projects with 60% Dependency Overlap

Package Manager Total Disk Usage Savings vs npm
npm 4,870 MB
pnpm 812 MB 83% less
yarn PnP 1,420 MB 71% less

pnpm's content-addressable store is the clear winner for disk efficiency. Because it hard-links from a global store, adding a new project that reuses existing packages costs almost nothing. This is especially impactful on CI machines and developer laptops with limited SSD space. Yarn PnP also saves significant space by storing compressed archives instead of extracted files. npm duplicates everything per project.

Monorepo Support

Monorepos are the default architecture for many organizations in 2026, and package manager support for workspaces is a critical factor.

npm Workspaces

npm introduced workspaces in v7. Configuration lives in the root package.json:


Enter fullscreen mode Exit fullscreen mode

Run commands across workspaces with -w or --workspaces:

# Install a dep in a specific workspace
npm install lodash -w packages/utils

# Run a script in all workspaces
npm run build --workspaces

# Run a script in a specific workspace
npm run test -w apps/web
Enter fullscreen mode Exit fullscreen mode

npm workspaces are functional but basic. There's no built-in task orchestration, no topological sorting for build order, and no parallel execution. For those features, you need to pair npm with tools like Turborepo or Nx.

pnpm Workspaces

pnpm's workspace support is configured via a pnpm-workspace.yaml file:

packages:
  - 'packages/*'
  - 'apps/*'
Enter fullscreen mode Exit fullscreen mode

pnpm provides rich workspace features out of the box:

# Install a dep in a specific workspace
pnpm add lodash --filter packages/utils

# Run a script across all workspaces
pnpm -r run build

# Run with topological sorting (dependencies first)
pnpm -r --workspace-concurrency=4 run build

# Filter by pattern
pnpm --filter "apps/*" run test
Enter fullscreen mode Exit fullscreen mode

pnpm includes built-in filtering, parallel execution, and dependency-aware task ordering. Its --filter flag supports glob patterns, directory paths, and dependency graph selectors like ...pkg-name (everything that depends on a package). This often eliminates the need for external orchestration tools.

yarn Workspaces

Yarn has the longest history with workspaces and v4 provides the most polished experience:


Enter fullscreen mode Exit fullscreen mode
# Run a command in a specific workspace
yarn workspace @myorg/utils add lodash

# Run a script across all workspaces
yarn workspaces foreach -A run build

# Run with topological ordering and parallelism
yarn workspaces foreach -A --topological --parallel run build
Enter fullscreen mode Exit fullscreen mode

Yarn v4 also provides constraints — a powerful feature that lets you enforce rules across all workspaces (e.g., "all packages must use the same version of React"). This is unique to yarn and extremely valuable for large monorepos.

Monorepo Feature Comparison

Feature npm pnpm yarn v4
Workspace declaration package.json pnpm-workspace.yaml package.json
Filtering Basic (-w flag) Advanced (--filter) Advanced (foreach)
Topological ordering No Yes Yes
Parallel execution No Yes Yes
Dependency graph selectors No Yes Limited
Cross-workspace constraints No No Yes

Security

Supply chain attacks have made package manager security a top priority. Each tool handles security differently.

npm

  • npm audit: Built-in vulnerability scanning that checks installed packages against the npm advisory database. Run npm audit to see issues and npm audit fix to auto-patch.
  • Package signing: npm supports package provenance via Sigstore, allowing publishers to prove a package was built from a specific commit in a public repository.
  • Flat node_modules: npm's hoisting behavior means packages can accidentally access undeclared dependencies (phantom dependencies). This is a security and reliability concern.

pnpm

  • Strict isolation: pnpm's non-flat node_modules structure means packages can only access their declared dependencies. This eliminates phantom dependencies entirely and prevents supply chain attacks that exploit hoisting.
  • pnpm audit: Same advisory database as npm, with pnpm audit command.
  • Side-effects cache: pnpm can cache the results of postinstall scripts, reducing the attack surface from install scripts.
  • Content integrity: The content-addressable store verifies file integrity by hash, making tampering detectable.

yarn

  • yarn audit: Vulnerability scanning via yarn npm audit.
  • Zero-installs: Yarn PnP supports committing your dependency cache to Git. This means CI installs nothing from the network — dependencies are verified at commit time and never re-downloaded. This is the strongest supply chain security posture of any package manager.
  • Checksums: Yarn v4 maintains integrity checksums in yarn.lock and verifies them on every install.
  • Plugin security: Yarn's plugin system is locked down — plugins must be explicitly installed and are version-controlled.

Security ranking: Yarn PnP with zero-installs offers the best protection against supply chain attacks. pnpm's strict isolation is the best defense against phantom dependency exploits. npm has improved significantly but its flat hoisting remains a structural weakness.

Lock Files Explained

Lock files ensure deterministic installs — every developer and CI machine gets the exact same dependency tree. Each package manager uses a different format.

package-lock.json (npm)

A JSON file that records the exact resolved version, integrity hash, and resolved URL for every dependency. It's verbose (often tens of thousands of lines for a medium project) but fully machine-readable.


Enter fullscreen mode Exit fullscreen mode

pnpm-lock.yaml (pnpm)

A YAML file that is more compact and human-readable than npm's lock file. It records the dependency graph structure separately from package metadata, making it easier to review in pull requests.


Enter fullscreen mode Exit fullscreen mode

yarn.lock (yarn)

A custom format (not JSON or YAML) that maps version ranges to resolved versions. Yarn v4's lock file includes checksums and is designed to minimize merge conflicts.

"express@npm:^4.21.0":
  version: 4.21.1
  resolution: "express@npm:4.21.1"
  checksum: 10c0/abc123...
Enter fullscreen mode Exit fullscreen mode

Key point: Never delete your lock file to "fix" dependency issues. Instead, use the package manager's built-in resolution commands. If you're experiencing JSON formatting issues when inspecting lock files, use a dedicated formatter tool.

Workspaces Deep Dive

Beyond basic monorepo support, each package manager handles workspace linking, dependency hoisting, and cross-package references differently.

Dependency Hoisting

npm hoists all dependencies to the root node_modules by default. This makes shared dependencies available to all packages but creates phantom dependency risks. You can disable hoisting with --install-strategy=nested, but this increases disk usage.

pnpm uses a symlinked structure that does not hoist by default. Each package gets its own node_modules with symlinks pointing to the global store. You can opt into hoisting with shamefully-hoist=true in .npmrc for compatibility, but strict mode is recommended.

yarn PnP eliminates node_modules entirely. The .pnp.cjs file maps import requests directly to zip archives in .yarn/cache. There is no hoisting — every import is explicitly resolved. Some tools require patches to work with PnP, though compatibility has improved dramatically in 2026.

Cross-Package References

In a monorepo, packages often depend on each other. Here's how each tool handles the workspace: protocol:


Enter fullscreen mode Exit fullscreen mode

Both pnpm and yarn replace workspace: references with actual version numbers at publish time, ensuring published packages have correct dependency declarations.

Migration Guide

Switching package managers is straightforward if you follow these steps.

Migrating from npm to pnpm

  • Install pnpm: npm install -g pnpm
  • Delete node_modules and package-lock.json
  • Run pnpm import to generate pnpm-lock.yaml from your existing package-lock.json (do this before deleting the lock file if you want to preserve exact versions)
  • Run pnpm install
  • Update CI scripts to use pnpm commands
  • Add pnpm-lock.yaml to version control and add package-lock.json to .gitignore

Migrating from npm to yarn

  • Enable corepack: corepack enable
  • Run yarn init -2 in your project root
  • Delete node_modules and package-lock.json
  • Run yarn install (generates yarn.lock automatically)
  • Decide on PnP vs node-modules linker. For maximum compatibility, add to .yarnrc.yml:
nodeLinker: node-modules
Enter fullscreen mode Exit fullscreen mode
  • Update CI scripts and commit yarn.lock and .yarnrc.yml

Migrating from yarn to pnpm

  • Install pnpm: npm install -g pnpm
  • Run pnpm import (reads yarn.lock and creates pnpm-lock.yaml)
  • Delete node_modules, yarn.lock, .yarnrc.yml, and .yarn/ directory
  • If using workspaces, create pnpm-workspace.yaml matching your workspace config
  • Run pnpm install and verify everything resolves

Pro tip: After migrating, run your full test suite and build process before committing. Differences in dependency resolution can surface as runtime errors. Use a JSON diff tool to compare your old and new lock files if you need to debug version mismatches.

Decision Matrix

Use this matrix to quickly identify which package manager best fits your situation:

Scenario Best Choice Why
Solo project, quick start **npm** Zero setup, ships with Node.js, huge community support
Monorepo with 5+ packages **pnpm** Best filtering, strict isolation, massive disk savings
Enterprise monorepo (50+ packages) **yarn v4** Constraints, zero-installs, mature plugin ecosystem
CI/CD speed is priority #1 **pnpm** or **yarn PnP** Both are 2-3x faster than npm on cached installs
Disk space constrained (CI, laptops) **pnpm** Content-addressable store saves 60-83% disk space
Maximum supply chain security **yarn PnP + zero-installs** No network fetches in CI, everything verified at commit
Strict dependency correctness **pnpm** Non-flat node_modules prevents phantom dependencies
Team with mixed experience levels **npm** Lowest learning curve, most tutorials and docs available
Migrating from yarn Classic (v1) **pnpm** Easier migration path than yarn v4, similar commands
React Native / Expo project **npm** or **yarn Classic** PnP compatibility issues; pnpm works with shamefully-hoist

Performance in CI/CD Pipelines

CI performance is where package manager choice has the biggest real-world impact. Here are optimized configurations for each tool.

npm in CI


Enter fullscreen mode Exit fullscreen mode

Always use npm ci instead of npm install in CI. It's faster because it skips the version resolution step and installs exactly what's in the lock file.

pnpm in CI


Enter fullscreen mode Exit fullscreen mode

yarn PnP in CI (Zero-Install)

# GitHub Actions example — no install step needed!
- name: Checkout
  uses: actions/checkout@v4

# Dependencies are already in the repo via .yarn/cache
- name: Build
  run: yarn build
Enter fullscreen mode Exit fullscreen mode

With yarn's zero-install approach, you skip the install step entirely. This can save 30-60 seconds per CI run. The tradeoff is a larger Git repository due to the committed cache. For detailed CI/CD pipeline optimization strategies, check our guide on building the best CI/CD pipeline for small teams.

Ecosystem Compatibility

Not every tool works perfectly with every package manager. Here's a compatibility overview for popular frameworks and tools as of 2026:

Tool / Framework npm pnpm yarn PnP
Next.js Full Full Full
Vite Full Full Full
React Native Full Needs shamefully-hoist Partial (use node-modules linker)
Electron Full Full Needs node-modules linker
Jest Full Full Full (with @yarnpkg/jest-resolver)
TypeScript Full Full Full (with @yarnpkg/sdks)
ESLint Full Full Full
Storybook Full Full Full (since Storybook 8)

The compatibility story has improved enormously since 2024. Most tools work with all three package managers, and PnP compatibility is no longer the deal-breaker it once was. If you encounter issues, check the developer tools directory for compatibility guides and workarounds.

Conclusion

There is no single "best" package manager in 2026 — the right choice depends on your project's specific needs. Here's the final summary:

  • Choose npm if you value simplicity, zero configuration, and the widest possible ecosystem compatibility. It's the safe default for solo projects, tutorials, open-source libraries, and teams with junior developers. npm v10 is genuinely good — just not the fastest or most disk-efficient option.
  • Choose pnpm if you care about disk space, install speed, and dependency correctness. Its strict non-flat node_modules prevents phantom dependencies, and the content-addressable store is a game-changer for machines running many projects. pnpm is the best all-around choice for monorepos that don't need yarn's advanced constraints.
  • Choose yarn v4 if you're running a large enterprise monorepo and want maximum control. Features like zero-installs, constraints, and the plugin system make yarn the most powerful option — but with a steeper learning curve. If you're still on yarn Classic (v1), consider migrating to pnpm unless you need yarn-specific features.

Whichever package manager you choose, make sure your entire team uses the same one. Add a "packageManager" field to your package.json (supported by corepack) to enforce consistency:


Enter fullscreen mode Exit fullscreen mode

This ensures that anyone running corepack enable will automatically use the correct package manager and version. For more developer productivity tips and tools, explore the full DevPlaybook tools collection.

Free Developer Tools

If you found this article helpful, check out DevToolkit — 40+ free browser-based developer tools with no signup required.

Popular tools: JSON Formatter · Regex Tester · JWT Decoder · Base64 Encoder

🛒 Get the DevToolkit Starter Kit on Gumroad — source code, deployment guide, and customization templates.

Top comments (0)