Migrating from NPM to Yarn

I have an Angular 2 project where I wanted to test out switching from npm to Yarn — a fast, reliable, and secure alternative npm client build by Facebook and others. Here is a quick and dirty run-through of my experience.

First, I wanted to benchmark npm performance to have something to compare the two, so I removed the node_modules folder.

rm -rf node_modules

Then, I wanted to see how long a regular npm install took (check out out gnomon for timing your CLI commands) and how big the resulting node_modules folder was.

$ npm install | gnomon
... tons of gibberish
... Total 96.9000s
// get the node_modules folder size
du -sh node_modules ... 213M node_modules

So, about 97 seconds for the install for a clean npm install resulting in a 213MB node_modules folder.

Now, we Yarn.

npm install -g yarn

Then, lets clean the node_modules folder again and benchmark how Yarn does the package installs.

$ rm -rf node_modules
$ yarn | gnomon
... Total 145.1798s
$ du -sh node_modules
... 266M node_modules

Wow — thats’s about 50% longer than the npm install, and a bit bigger of a node_modules folder as well. What gives? First let’s do the same exact thing again… just trust me.

$ rm -rf node_modules
$ yarn | gnomon
... Total 16.15s.

Now it’s only 16 seconds! It seems as though although the first Yarn install took 50% longer (than npm), the second was 80% faster (the folder size is the same as the first yarn install, so no improvements in folder size compared to npm that I can see… at least for this project).

The slowdown the first go-round is likely due to Yarn’s deterministic nature, called Flat Mode, ensuring all developers have the same exact node_modules structure. With npm, the node_modules tree can be different across developer’s machines as the web of dependencies can be different depending on what order dependencies were installed.

The speedup the second time around was due to Yarn’s package caching which (in their words) caches every package it downloads so it never needs to again. So, rather than going out to going remotely to the npm registry and downloading every package over again, it’ll check in your local cache first. This also allows you to download packages without an internet connection.

Yarn is obviously very young and could be looked at at just another notch in the ever-growing Node ecosystem. However, the switching cost is almost zero for at least giving it a try as it is a simple CLI tool and works with your existing package.json (it also works with Bower) and requires no code changes, Yarn just creates a yarn.lock file that looks like below:

# yarn lockfile v1
version "2.0.0"
resolved "https://registry.yarnpkg.com/@angular/common/-/common-2.0.0.tgz#6d5b38cef8bec69726590f395da10c2d8XXXXXX9X"
version "2.0.0"
resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-2.0.0.tgz#724e7c68ac177aa933aa75a6b4cb11e5XXXXXXaa"
version "2.0.0"
resolved "https://registry.yarnpkg.com/@angular/core/-/core-2.0.0.tgz#87b5ea4a7ae063d27bcf2332a4aa932dXXXXX88"

I am interested to see:

  • how much quicker it can make my workflow (duh)
  • how it handles version changes and the dependencies that go with those
  • whether installs are quicker and whether the caching really does make a noticeable workflow difference (…I do download a lot of the same libraries like moment, jquery, underscore, bootstrap, etc. for a lot of projects)
  • if it can somehow untangle some of the dependency mess that is npm

The good thing is that npm is fully on board with Yarn and wants to see them grow and flourish - open source at it’s finest. Excited to see where it goes.