As a developer, your always stressed for time. This need to launch faster, release faster and YOU have to code faster. For a long time, we used node together with npm4 to handle our package bundling and other front-end functionality. It worked great up to a point. We discovered that npm4 produced time sinks in terms of installing time and version locking. Being pressed for time, this was not optional.
What we discovered
- Installing packages from scratch = time sink
- Switching between branches might cause package.json file to change (for whatever reason) and cause a mandatory install = time sink
- Our build servers install packages, each build leading to a longer build time when there are added or removed packages = time sink
- Versions of packages aren’t locked so we can’t guarantee that all members sharing a repository will install the exact same version of packages = time sink
Something had to change. Preferably our package manager, and we found some interesting results, so let’s begin.
What should you consider before switching package manager
Starting from the absolute beginning, the most obvious attribute to consider is, above all, performance since all package managers accomplish the same task, (installing node modules). But there might be some minor, but important, differences to consider such as lock file and package integrity control, but more on that later. Let’s take a look at some attributes!
In order to determine which package manager has the best performance we had to make a few tests. Since cache has a great overall effect on install time it’s important to measure scenarios when cache is absent and when it’s not, to get an accurate measurement.
I got 5 (measurements) on it
Below you’ll find a table with 3 of our selected package managers which we wanted to test against each other: NPM 4.6.1, NPM 5.5.1 and YARN. We made 5 measurements for each package manager, both when cache is absent and when it is not. Each measurement was recorded when 32 packages from our package.json file was installed. From these 5 measurements, we choose an average so that we can leave out coincidence.
Install time in seconds for each package manager
The most obvious result is that npm4 is very slow in comparison to its big brother npm5, and even slower when compared to Yarn. And furthermore, this fact stays true in both scenarios when cache is absent and when it isn’t.
Another thing to notice is when cache is absent is that npm5 measure in at about the same time as Yarn, but when cache exists, Yarn is a twice as fast, good for you!
Let’s boil down these results into a new table where we use npm4 as the baseline measurement.
Install time for each package manager in % faster and multiplier compared to npm4
In the table above, we can see how many % faster each package manager performs compared to npm4. We see that npm5 and Yarn is 3 times faster than npm4 when cache is absent. When cache exists npm5 is about 3.3 times faster, and Yarn is a staggering 5.75 times faster.
- npm4 is slow
- npm5 is 3 times faster than npm4
- Yarn performs almost the same as npm5 when cache is absent, but 2 times faster than npm5 when cache exists
And now… minor – but important – differences
Both npm5 and Yarn produce a lock file. A lock file provides a way to essentially take a snapshot of installed packages and their dependencies. This means that it’s possible to share package.json and guarantee that a group of collaborators can produce the exact same set of installed packages.
Say goodbye to “it works on my machine”.
But let’s take a look at examples of lock files below
As one can see above, Yarn produces a less complex dependency structure compared to npm5, and because of that fact it’s less prone to cause merge conflicts which might be something to consider when collaborating with others.
A unique feature about npm5 is the integrity field (subresource integrity field), it’s a checksum produced from the package content. This field is compared against the checksum of the package you’re trying to download. It's therefore possible to guarantee that not only the exact same version is installed but also the content within. Neat!
Summary – we have a winner!
Both npm5 and Yarn provide great improvement in terms of install time and version locking. I do find Yarn favorable since it’s twice as fast as npm5 when packages are cached. Lock files in Yarn are less prone to cause merge conflicts because of its less complex dependency structure and might be favorable when collaborating with others. On the other hand, npm5 can thanks to the sub resource integrity field guarantee that not only the version is correct but the content as well, a bit more secure in other words.
You can’t really go wrong with npm5 or Yarn since they both improve performance and version locking. But for us, Yarn takes the upper hand since it’s twice as fast compared to npm5 when cached. Yarn is also less prone to cause merge conflicts which is valuable when working a cross teams.
All in all, Yarn is potentially the biggest time saver for us. Which is a big thing when your pressed for time.