NPM Vs Yarn 2019
New year, old package management
Recently my team has been running into a an odd bug in development:
You can read the actual Github issue I created: https://github.com/palantir/blueprint/issues/3254
This error would constantly be appearing whenever this component calling this function would get mounted. Turns out that we had a conflicting, nested version of React installed inside of our node_modules. So how did this happen? After some research it seems that this conflicting version of React would only get installed when running
yarn install. Deleting my node_modules and running
npm install reliably installed my dependencies correctly causing this error to disappear. With this new discovery I’m compelled to make my team switch over from using Yarn to NPM. This has lead me to research more about the differences between these two package management systems.
When looking at this problem it’s good to look back and understand what made Yarn an attractive alternative to begin with. I’ve narrowed it down to two big reasons. Speed and the auto-generated lock file. Let’s talk about the more complicated of the two; yarn.lock
What is the lock file
Say you’re working on a project and you have v1.4.0 of “Foo” installed as a dependency. In your package.json file, you have “Foo” listed as a dependency using semver:
"Foo": ^1.0.0. You develop your feature and push it to the remote branch. Your coworker then pulls your feature, runs
npm install, but the feature you’ve just built doesn’t work. You simply look to him, shrug and say, “It works on my machine”. After some investigation you find that your coworker has version 1.7.0 of “Foo” installed which works a little different from the earlier 1.4.0 version you were using when developing. Because the package is using the
^symbol in your package.json, it will install the latest minor version which is why your coworker is on version 1.7.0 when he ran `npm install`. To avoid this problem, you would have to explicitly state each package’s version in your package.json. What a pain. This is where the lock file comes in.
The lock file will literally “lock” the installed dependencies’ version. The first time you run
yarn it will auto generate a yarn.lock file for you. This lock file will record each of the installed dependencies version’s into it. So when your coworker pulls the remote and runs
yarn he’s guaranteed to have the same versions of the packages that you are using.
This innovation was very attractive and was one less thing developers had to worry about. However, as of NPM v5.0.0, NPM will auto generate it’s own lock file which does the same thing. Yarn did it first, but that’s hardly an “advantage” over NPM today.
When Yarn burst onto the scene it touted that it was nearly twice as fast as NPM. Which WAS true. Yarn was much much faster and saved a lot of time. However, is this still true today? No, it’s not true. I don’t have any benchmarks to give you, but I implore you to test it yourself. Remove your node_modules or a package and install it again with NPM and Yarn. Is Yarn faster? Yeah, sure. Is it twice as fast? No way.
After analyzing Yarn Vs. NPM in this light, I don’t see much of a benefit to using Yarn anymore. Sure, it still installs packages slightly faster than NPM, but the cost at which it does it is not worth it. That cost being the reason why I began writing this article. As I mentioned in the beginning, re-installing my node_modules using NPM instead of Yarn fixed this odd conflicting React instance living inside my node_modules. The exact reason for why this was happening is pretty deep and I’ll doubt I’ll ever know exactly what it was, but it does shed light on one of the biggest advantages of NPM; It is simply more mature, is backed by a bigger community and is more reliable than Yarn. Yarn is still relatively new, maybe it will innovate in a great way with a new must-have feature in the near future, but for now I think I’ll go back to old faithful.
Note: If you want an in depth explanation of how NPM and package management works, check out this great article by Alexis King