Yarn versus npm, what's the big deal?

By: (plus.google.com) +David Herron; Date: Tue Sep 19 2017 17:00:00 GMT-0700 (Pacific Daylight Time)

Tags: Node.JS

A couple years ago Yarn came onto the Node.js scene promising to be a better npm than npm. Apparently a lot of people have taken to Yarn, given the frequency with which I see instructions to install packages using Yarn. Since npm is installed along with Node.js, and since Yarn just uses the npm package repository, I'm left wondering what all the fuss is about Yarn. If it's just doing the same thing as npm then what is its reason to exist? What advantage does Yarn have over npm? Let's take a look.

Let's start by looking at the promises made on the Yarn website -- (yarnpkg.com) https://yarnpkg.com/en/

  • Ultra Fast - Yarn accomplishes this by caching every package it installs locally.
  • Mega Secure - Checksums verify the integrity of packages before installation, and before its code is executed.
  • Super Reliable - The yarn.lock file records precise exact package versions so that everyone on your team is in lock step and you don't have bugs from version creep.

At the time Yarn was introduced, back in 2016, npm was rather slow. I think the speed factor is the major selling point for Yarn. However the npm team have not taken the competition lightly. Over the last couple years npm's performance has improved.

According to npm, npm@5 (a.k.a. npm@latest) they've spent the last year and a half making some major improvements to npm. That time-frame predates Yarn's existence (a year-and-a-half before May 2017 is in late 2015), so npm did not make those improvements as a response to Yarn. Maybe. (blog.npmjs.org) http://blog.npmjs.org/post/161276872334/npm5-is-now-npmlatest

In any case the high level points of the npm@5 announcement is: a) It's fast, b) It's consistent (due to a lock file)

Further, npm@5 is now the default with Node.js v8 and beyond. This latest version of npm may be improved enough to warrant ignoring Yarn.

Yarn uses the same package.json format as used by npm. Yarn doesn't have its own package repository. Instead Yarn gets package information from the npm repository, and when a user publishes a package using Yarn the package is published to the npm package repository. (yarnpkg.com) https://yarnpkg.com/en/docs/publishing-a-package

Yarn is so similar to npm that they've published a migration guide showing the command line options are nearly identical: (yarnpkg.com) https://yarnpkg.com/en/docs/migrating-from-npm

Kicking the tires

Installation for me - a Mac OS X user who prefers MacPorts - is:

$ sudo port install yarn
Password:
Warning: port definitions are more than two weeks old, consider updating them by running 'port selfupdate'.
--->  Computing dependencies for yarn
--->  Fetching archive for yarn
--->  Attempting to fetch yarn-0.24.4_0.darwin_15.noarch.tbz2 from https://packages.macports.org/yarn
--->  Attempting to fetch yarn-0.24.4_0.darwin_15.noarch.tbz2.rmd160 from https://packages.macports.org/yarn
--->  Installing yarn @0.24.4_0
--->  Activating yarn @0.24.4_0

It installs an old version, Yarn 1.0 has been released. But that might be because my port definitions are more than two weeks old.

I'm also told this:

  yarn has the following notes:
    yarn stores data in:
    
        ~/.yarn
        ~/.yarnrc
        ~/.cache/yarn
        ~/.config/yarn
    
    Should you choose to install packages globally with yarn (yarn global add), these files will not be removed if you deactivate or uninstall yarn. By default, these packages will
    be installed in ~/.config/yarn/global, and soft-linked to /opt/local/bin. To uninstall them all:
    
    $ ls -1 $HOME/.config/yarn/global/node_modules/  | xargs sudo yarn global remove
    
    You may then remove the directories listed above and uninstall yarn.
    
    yarn is meant to replace NPM, and may cause conflicts if you use both.
    
    You may override the default global installation directory by setting the PREFIX environment variable, e.g.
    
    mkdir -p $HOME/.config/yarn/bin # Or wherever you want
    export PREFIX=$HOME/.config/yarn/bin
    export PATH=$PREFIX:$PATH

That's easily accomplished with:

$ vi ~/.profile

Followed by starting a new shell, or else running those commands by hand.

I ran this in my home directory expecting to see a USAGE message:

$ yarn
yarn install v0.24.4
info No lockfile found.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 📃  Building fresh packages...
success Saved lockfile.
✨  Done in 0.18s.

But, instead, as you see, it did some installation. Not finding a lockfile it helpfully created a yarn.lock, and it also created an empty node_modules directory. Not exactly what I expected since my home directory is not a working project directory. That meant removing those two files to sanitize my home directory.

The command yarn help is the correct way to get the USAGE message. Sigh.

Running yarn in an actual project directory:

$ time yarn
yarn install v0.24.4
info No lockfile found.
warning green-transportation-info: No license field
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 📃  Building fresh packages...
success Saved lockfile.
warning Your current version of Yarn is out of date. The latest version is "1.0.2" while you're on "0.24.4".
✨  Done in 29.73s.

real	0m30.488s
user	0m17.598s
sys	0m8.736s

The yarn.lock is a YAML file listing precise version numbers as well as URL's from which to retrieve packages. Here's an example from the file:

akasharender@>=0.5, akasharender@>=0.5.14, akasharender@>=0.6:
  version "0.6.10"
  resolved "https://registry.yarnpkg.com/akasharender/-/akasharender-0.6.10.tgz#85e87d47e01fe9a471efc3e7975696fabf49c741"
  dependencies:
    asciidoctor.js "1.5.6-preview.2"
    async "^1.5.2"
    cmnd "0.0.6"
    co "*"
    debug "^2.2.0"
    ejs "^2.4.1"
    flat-cache "^1.2.2"
    fs-extra ">=4.0.1"
    globfs ">=0.2"
    gray-matter "^2.x"
    less ">=2.7"
    markdown-it "^5.1.0"
    oembetter "*"
    rss "^1.2.1"

It's interesting that the package URL is via registry.yarnpkg.com. It would appear the Yarn team maintains a mirror of the main npm repository.

To compare:

$ time npm install
... lots of output

real	0m54.560s
user	0m31.978s
sys	0m9.448s
$ npm -v
3.10.10
$ which npm
/Users/david/.nvm/versions/node/v6.11.2/bin/npm

Hm, that's quite a bit slower. This is an out-of-date version of Yarn versus an out-of-date version of npm, and npm was twice as slow (approximately).

Updating to the latest npm is (because I'm using nvm to manage Node.js versions) this simple:

$ nvm install 8
v8.5.0 is already installed.
Now using node v8.5.0 (npm v5.3.0)

Then rerun the test

$ rm -rf node_modules/
$ time npm install
... lots of output
added 402 packages in 359.632s

real	6m0.999s
user	0m25.469s
sys	0m9.469s

Um, really? Now it's 18x slower. There is a new file, package-lock.json, that is in JSON format and whose format is rather similar to the yarn.lock file.

There's also a new directory containing a bunch of packages:

$ ls -ld ~/.npm
drwxr-xr-x  1794 david  staff  60996 Sep 21 15:20 /Users/david/.npm

So let's re-run the test to see if the local cache will speed things up.

$ rm -rf node_modules/
$ time npm install
... lots of output
added 402 packages in 24.33s

real	0m25.170s
user	0m15.065s
sys	0m5.630s

Yup, that performance is on-par with Yarn's performance.

Summary

I see no compelling reason to switch to Yarn. Bottom line is that Yarn's primary purpose for existence was to be faster than npm, and npm has improved their performance considerably. I don't see any feature of Yarn that screams to me that I must use Yarn.

When Yarn was announced, the npm team responded by welcoming the competition. You'd think that since Yarn is piggybacking off the hard work npm, Inc. performs to set up and maintain and monitor and police the npm Registry, that npm, Inc. would be upset. You could see Yarn as a freeloader organization. But that would be to misunderstand the ethos of the open source ecosystem.

Instead, npm, Inc., took this as a challenge and took it upon themselves to improve their product. As a result npm is much better than it had been.

« Node.js forked, Ayo.JS, is trying to find its way Loading jQuery and Bootstrap in Electron app has a curious bug »
2016 Election 2018 Elections Acer C720 Ad block Air Filters Air Quality Air Quality Monitoring AkashaCMS Amazon Amazon Kindle Amazon Web Services America Amiga and Jon Pertwee Android Anti-Fascism AntiVirus Software Apple Apple Hardware History Apple iPhone Apple iPhone Hardware April 1st Arduino ARM Compilation Artificial Intelligence Astronomy Astrophotography Asynchronous Programming Authoritarianism Automated Social Posting AWS DynamoDB AWS Lambda Ayo.JS Bells Law Big Brother Big Data Big Finish Big Science Bitcoin Mining Black Holes Blade Runner Blockchain Blogger Blogging Books Botnets Cassette Tapes Cellphones China China Manufacturing Christopher Eccleston Chrome Chrome Apps Chromebook Chromebox ChromeOS CIA CitiCards Citizen Journalism Civil Liberties Climate Change Clinton Cluster Computing Command Line Tools Comment Systems Computer Accessories Computer Hardware Computer Repair Computers Conservatives Cross Compilation Crouton Cryptocurrency Curiosity Rover Currencies Cyber Security Cybermen Cybersecurity Daleks Darth Vader Data backup Data Formats Data Storage Database Database Backup Databases David Tenant DDoS Botnet Department of Defense Department of Justice Detect Adblocker Developers Editors Digital Nomad Digital Photography Diskless Booting Disqus DIY DIY Repair DNP3 Do it yourself Docker Docker MAMP Docker Swarm Doctor Who Doctor Who Paradox Doctor Who Review Drobo Drupal Drupal Themes DVD E-Books E-Readers Early Computers eGPU Election Hacks Electric Bicycles Electric Vehicles Electron Eliminating Jobs for Human Emdebian Encabulators Energy Efficiency Enterprise Node EPUB ESP8266 Ethical Curation Eurovision Event Driven Asynchronous Express Face Recognition Facebook Fake News Fedora VirtualBox Fifth Doctor File transfer without iTunes FireFly Flash Flickr Fraud Freedom of Speech Front-end Development G Suite Gallifrey Gig Economy git Github GitKraken Gitlab GMAIL Google Google Chrome Google Gnome Google+ Government Spying Great Britain Green Transportation Hate Speech Heat Loss Hibernate High Technology Hoax Science Home Automation HTTP Security HTTPS Human ID I2C Protocol Image Analysis Image Conversion Image Processing ImageMagick In-memory Computing InfluxDB Infrared Thermometers Insulation Internet Internet Advertising Internet Law Internet of Things Internet Policy Internet Privacy iOS iOS Devices iPad iPhone iPhone hacking Iron Man iShowU Audio Capture iTunes Janet Fielding Java JavaFX JavaScript JavaScript Injection JDBC John Simms Journalism Joyent Kaspersky Labs Kext Kindle Kindle Marketplace Large Hadron Collider Lets Encrypt LibreOffice Linux Linux Hints Linux Single Board Computers Logging Mac Mini Mac OS Mac OS X MacBook Pro Machine Learning Machine Readable ID Macintosh macOS macOS High Sierra macOS Kext MacOS X setup Make Money Online Make Money with Gigs March For Our Lives MariaDB Mars Mass Violence Matt Lucas MEADS Anti-Missile Mercurial MERN Stack Michele Gomez Micro Apartments Microsoft Military AI Military Hardware Minification Minimized CSS Minimized HTML Minimized JavaScript Missy Mobile Applications Mobile Computers MODBUS Mondas Monetary System MongoDB Mongoose Monty Python MQTT Music Player Music Streaming MySQL NanoPi Nardole NASA Net Neutrality Network Attached Storage Node Web Development Node.js Node.js Database Node.js Performance Node.js Testing Node.JS Web Development Node.x North Korea npm NVIDIA NY Times Online advertising Online Community Online Fraud Online Journalism Online Photography Online Video Open Media Vault Open Source Open Source and Patents Open Source Governance Open Source Licenses Open Source Software OpenAPI OpenJDK OpenVPN Palmtop PDA Patrick Troughton PayPal Paywalls Personal Flight Peter Capaldi Peter Davison Phishing Photography PHP Plex Plex Media Server Political Protest Politics Postal Service Power Control President Trump Privacy Private E-mail server Production use Public Violence Raspberry Pi Raspberry Pi 3 Raspberry Pi Zero ReactJS Recaptcha Recycling Refurbished Computers Remote Desktop Removable Storage Republicans Retro Computing Retro-Technology Reviews RFID Rich Internet Applications Right to Repair River Song Robotics Robots Rocket Ships RSS News Readers rsync Russia Russia Troll Factory Russian Hacking Rust SCADA Scheme Science Fiction SD Cards Search Engine Ranking Season 1 Season 10 Season 11 Security Security Cameras Server-side JavaScript Serverless Framework Servers Shell Scripts Silence Simsimi Skype SmugMug Social Media Social Media Networks Social Media Warfare Social Network Management Social Networks Software Development Software Patents Space Flight Space Ship Reuse Space Ships SpaceX Spear Phishing Spring Spring Boot Spy Satellites SQLite3 SSD Drives SSD upgrade SSH SSH Key SSL Stand For Truth Strange Parts Swagger Synchronizing Files Tegan Jovanka Telescopes Terrorism The Cybermen The Daleks The Master Time-Series Database Tom Baker Torchwood Total Information Awareness Trump Trump Administration Trump Campaign Twitter Ubuntu Udemy UDOO US Department of Defense Video editing Virtual Private Networks VirtualBox VLC VNC VOIP Vue.js Walmart Weapons Systems Web Applications Web Developer Resources Web Development Web Development Tools Web Marketing Webpack Website Advertising Weeping Angels WhatsApp William Hartnell Window Insulation Windows Windows Alternatives Wordpress World Wide Web Yahoo YouTube YouTube Monetization