The trigger
A dependency conflict caused different versions of a package to load depending on import order. npm flattened the tree in a way that masked it locally but broke in CI.
pnpm's model
pnpm uses a content-addressable store. Each package version is stored once. Symlinks compose the virtual node_modules. Phantom dependencies become errors, not silent surprises.
Practical differences
node_modulesis 3× smaller (shared store across projects)- Workspace support is first-class and fast
pnpm why <package>is invaluable for auditing
The one downside
Some tools still assume a flat node_modules. Electron builders and some native addon tools need a --shamefully-hoist flag as a workaround.