Run du -sh node_modules on two projects: a small one with fifteen dependencies, and a monorepo with four apps sharing internal packages. On the first one, you won't notice any difference between npm and pnpm. On the second one, if you're still on npm, you're going to have the same copy of React, TypeScript and the same devDependencies repeated four times on disk — once for every workspace package that declares them.

That's the real problem. It's not "pnpm is faster" in the abstract. It's that the space and time savings depend on how much duplication your original install had, and that duplication grows with the number of packages in the monorepo, not with the total number of dependencies.

My thesis: pnpm wins in monorepos and in CI because of the symlink model, but npm is still the zero-friction choice for small projects where the learning curve isn't worth it. This isn't an aesthetic preference. It's a calculation that changes depending on the size of the repo.

The real difference between npm and pnpm: what each one stores on disk

npm installs every dependency as a physical copy inside node_modules. If you have four packages in a workspace and all four depend on lodash@4.17.21, npm — unless you use aggressive hoisting, which brings its own phantom-dependency problems — can end up with that same version copied in more than one place in the tree.