npm's flat tree
npm maintains a flattened dependency tree as of version 3. This leads to less
disk space bloat, with a messy
node_modules directory as a side effect.
On the other hand, pnpm manages
node_modules by using hard linking and
symbolic linking to a global on-disk content-addressable store. This nets you
the benefits of far less disk space usage, while also keeping your
node_modules clean. There is documentation on the store layout if you wish
to learn more.
The good thing about pnpm's proper
node_modules structure is that it
"helps to avoid silly bugs" by making it impossible to use modules that are not
specified in the project's
pnpm does not allow installation of packages without saving them to
package.json. If no parameters are passed to
pnpm add, packages are saved as
regular dependencies. Like with npm,
--save-optional can be
used to install packages as dev or optional dependencies.
As a consequence of this limitation, projects won't have any extraneous packages when they use pnpm unless they remove a dependency and leave it orphaned. That's why pnpm's implementation of the prune command does not allow you to specify packages to prune - it ALWAYS removes all extraneous and orphaned packages.
Directory dependencies start with the
file: prefix and point to a directory in
the filesystem. Like npm, pnpm symlinks those dependencies. Unlike npm, pnpm
does not perform installation for the file dependencies.
This means that if you have a package called
<root>/foo) that has
bar@file:../bar as a dependency, pnpm won't perform installation for
<root>/bar when you run
pnpm install on
If you need to run installations in several packages at the same time, for
instance in the case of a monorepo, you should look at the documentation for