Facebook recently released an alternative to Node Package Manager (npm). It’s called Yarn and, according to the developers, is designed to improve on npm in the following areas:
Let’s examine each of these claims in more detail.
Yarn claims to be a faster than npm. I ran a test where I installed all the packages for one of my medium-sized React applications. Yarn completed in about a quarter of the time taken by npm—20 secs vs 78 secs.
Given it draws packages from the same locations how does it achieve this? Simple. It downloads libraries in parallel. Once it has calculated the necessary dependencies it begins downloading them at the same time. npm, in contrast, downloads them one at a time.
Another performance benefit of Yarn is that it caches packages on the local machine. So, if you delete the packages from the project and install them again it’s almost instantaneous—as it pulls packages from the cache rather than getting them from remote repositories.
Caching also has the side-effect of allowing you to install packages when off-line. So, if you are on a flight and installing libraries you usually use, it’ll just work.
Determinism refers to the ability of the package manager to deliver expected, reproducible results every time it’s used. This is important to ensure that anyone using the package manager to recreate the project gets the expected results. If the project isn’t recreated faithfully then it may not run, or may run with unexpected behavior—or, as we call them in the business, bugs.
This seems like a pretty essential and uncontroversial requirement for a package manager. But it’s one that’s not met by npm—at least in its default behavior.
Let’s say I install React in my project. To do this in npm I would use the following command
npm install --save react
This would create an entry in my
package.json file like
^ symbol here indicates that npm can install more recent versions of React that 15.3.0—as long as they have the same major revision number. So, 15.4.0 could be OK, but not 16.0.0.
This is an example of good intentions failing. There shouldn’t be breaking changes in a minor revision so, using the npm approach, you get things like performance improvements and bug fixes that have been made since the library was installed, but your application doesn’t break.
However, this relies on package developers using release numbers correctly and not making mistakes by introducing breaking changes in a minor release. Willing to trust the administrative skills of your fellow developers? No? Precisely.
To its credit npm has a solution to this problem. You can snapshot the dependencies using
This produces a
npm-shinkwrap.json file that documents exact versions of dependencies—allowing faithful recreation of the project. However, it’s not the default behavior and the shinkwrap file needs to be maintained.
To install React using Yarn use
yarn add React
First, note that there’s no need to add
--save (or similar). You almost always want to save the package to
package.json so having this as default behavior is nice.
If I look at my
package.json file after installing React using Yarn I see the following entry
^ symbol—so I’m referring to a unique version of the package. Yarn will also generate a
yarn.lock file that stores version details of dependencies of the packages you have installed—and hashes of these packages. This ensures that you are restoring exactly the same packages every time.
These checksums also form the basis of Yarn’s security claims. The integrity of every installed package is verified before any code is executed. This is the default behavior in Yarn so, again, you will obtain this benefit for “free.”
If you are migrating a project from npm run the following command in the project root to set things up
The Yarn site contains an invaluable side-by-side comparison of common npm commands and their Yarn equivalents that are worth bookmarking.