<m>There are 3 dominant package managers for JavaScript: npm, Yarn, pnpm.
Ask any JS dev about which one they prefer and you can be pretty sure they will have lots of good reasons for why their favorite is the best:</m>
<m> "*Yarn is the fastest*" <br>
"*pnpm package installation is more space efficient*" <br>
"*npm is the best maintained*" <br></m>
<m>The package management landscape is changing fast and what may have been good arguments 1 or 2 years ago may no longer be valid today.
For example, when yarn was initially released, it was touted as being a fast alternative to npm.
However, Yarn's speed advantage came primarily through offline caching, a feature that has since been implemented in npm, as well.
The same is true for locked dependency versions (learn more about managing lock files [here](https://www.coana.tech/post/navigating-lock-files-best-practices-and-tips)), which is also supported by npm today.
Doing a detailed comparison between the package managers is complicated due to their vast feature sets and tendency to change extremely fast.
In this post, I will refrain from nitty-gritty detailed comparisons of specific features but instead, look at the major differences that are likely to play an important role.
If you just want the short TLDR, see my short assessment below, otherwise, read on!</m>
<m>- **npm**: The safe choice. Good enough for most practical uses, but with serious performance bottlenecks in large applications.
- **Yarn Classic**: The bad choice. Superseded by npm. I wouldn't use it on any new project.
- **Yarn Berry**: The bold choice. Potentially the best performance, but be prepared to deal with compatibility issues.
- **pnpm**: The smart choice. Very good performance paired with high npm compatibility. Currently, my goto package manager.</m>
<m>### npm
npm is the original package manager for Node.js applications.
Since npm is the default package manager installed with Node, it's also the most commonly used.
Today npm is pretty feature-rich and the reasons for choosing one of the alternatives are fewer than what they used to be.
For example, many devs would previously have picked Yarn due to the [Yarn workspaces](https://classic.yarnpkg.com/lang/en/docs/workspaces/) feature for working with mono repositories, but workspaces is also supported by npm since version 7 ([learn more about workspaces here](https://docs.npmjs.com/cli/v7/using-npm/workspaces)).
For most developers and most projects, npm will be just fine, and you may find comfort in the fact that npm is a well-maintained project owned by GitHub and therefore unlikely to die soon.
The biggest disadvantage of npm is that it uses a package installation scheme that may result in duplicated packages and slow installation times.</m>
<m>### Yarn
Yarn is more like two package managers than one.
There is Yarn Classic (version 1), which is the original contender to npm's dominant position.
Anecdotally, I have found that most people who say they use Yarn actually still use Yarn Classic.
Today, I would not pick Yarn Classic for any new project.
It doesn't really offer anything substantial over npm and it's less well-maintained.</m>
<m>Then there is Yarn Berry (version 2 and 3), a more radical alternative that tries to redefine package management through its controversial [Plug'n'Play](https://yarnpkg.com/features/pnp)(PnP) system.
With PnP, dependencies are bundled in a file called .pnp.cjs instead of installed as individual packages in the node_modules folder.
Yarn patches the module loading mechanism to extract packages from .pnp.cjs instead of the node_modules folder.
This mechanism solves some of the problems with the node_modules strategy like slow installation time, slow startup times for Node.js, duplicated packages, and lots of I/O during installations.
It's also possible to commit the .pnp.cjs file in case you want to run the app without doing a `yarn install` first, for example, in CI environments.
Yarn Berry's biggest disadvantage is that it's not completely compatible with all tools and packages, and you sometimes need plugins for it to work with bundlers and such.
I've tried to convert a npm project to Yarn Berry a couple of times but always failed due to compatibility issues.
I'm sure it was probably more my lack of skill and grit than actual technical limitations that lead to the failure.
Never the less, I don't think the limitations of node_modules justify the risk of moving to an alternative solution that may result in compatibility issues down the line.
Granted, it may be different for people who work on enterprise-scale applications where `npm install` time is measured in multiple minutes.</m>
<m>### pnpm
The pnpm package manager is by far my favorite of the 3 package managers.
It's similar to npm and Yarn classic in that it adheres to the classic installation strategy of placing dependencies in the node_modules folder.
The primary feature that sets it aside is that it places the actual physical packages in a folder called node_modules/.pnpm and creates the node_modules tree structure through hard links to the folders in node_modules/.pnpm.
By using this strategy, pnpm never installs two versions of the same package leading to optimal space performance.
Because the folder structure is so similar to npm, it's almost completely compatible with npm, which makes switching between the two package managers low effort.
The only compatibility issue I found when converting to pnpm is how pnpm deals with phantom dependencies (a topic we cover [here](https://www.coana.tech/post/a-quick-introduction-to-phantom-dependencies)).
In practice, pnpm installations are much faster than npm, and often comparable to or better than those of Yarn Berry.
If you want to learn more about how we migrated to pnpm and Coana, you can read our blog post about the process [here](https://www.coana.tech/post/getting-started-with-pnpm-to-reduce-your-package-installation-time-10x).</m>
<m>### Final remarks
This post is quite opinionated and there are lots of nuances about the package managers that I'm not aware of or haven't included.
However, if you still want to tell me just how wrong I am, you are more than welcome to hit me up on [Twitter](https://twitter.com/torp_martin).</m>