Why You Might Want to Switch to pnpm from npm
I switched a monorepo with 12 packages from npm to pnpm. Install time dropped from 4 minutes to 45 seconds. Disk usage dropped by 60%.
7 Sept 2024

I switched a monorepo with 12 packages from npm to pnpm. Install time dropped from 4 minutes to 45 seconds. Disk usage dropped by 60%.
Here's why.
It doesn't duplicate packages
npm copies every dependency into each project's node_modules. If ten projects use the same version of lodash, you get ten copies.
pnpm stores packages in a global content-addressable store and creates hard links. One copy on disk, shared everywhere. On a machine with many projects, this saves gigabytes.
Faster installs
pnpm installs packages in parallel and uses its global cache aggressively. Once a package is downloaded, it's available to every project on the machine without re-downloading.
In practice, this means CI pipelines and fresh clones are significantly faster.
Strict dependency resolution
npm has a problem called "phantom dependencies." Your code can accidentally import a package that's installed as a transitive dependency — one you never listed in your package.json. It works until someone upgrades the parent package and the transitive dep disappears.
pnpm prevents this. It only makes your declared dependencies accessible. If you didn't list it, you can't import it. This catches real bugs.
Built for monorepos
pnpm's workspace feature handles multi-package repos natively. Shared dependencies are hoisted correctly. Versions stay consistent. No need for separate tools like Lerna for basic workspace management.
Better lockfile
pnpm-lock.yaml is more deterministic than package-lock.json. It produces more consistent and reproducible builds across different machines and CI environments.
The trade-off
pnpm is faster, more disk-efficient, and stricter about dependency correctness. For monorepos, it's the clear winner.
The cost: some packages assume npm's flat node_modules structure and break under pnpm's strict isolation. You'll occasionally need to add entries to .pnpmfile.cjs or use shamefully-hoist to fix compatibility issues. And your team needs to learn a slightly different CLI — pnpm add instead of npm install, pnpm dlx instead of npx.
For most projects, those are small prices for big gains.
Keep reading
- oxlint vs ESLint: Why I Replaced ESLint with oxlint
- Lefthook vs Husky: Why I Switched and Never Looked Back
- The Frontend Toolchain Is Now Written in Rust and Go. What That Means for You
- Publishing Your TypeScript Package to npm: A Step-by-Step Guide
- Replace Axios with a Simple Custom Fetch Wrapper (Production-Ready Guide)