JavaScript
Article

Yarn vs npm: Everything You Need to Know

By Tim Severien

This article was peer reviewed by Adrian Sandu, Marcello La Rocca, Matt Burnett, Nuria Zuazo and Vildan Softic. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

2016.10.26: Article was updated to address points raised in the comments.

Yarn is a new JavaScript package manager built by Facebook, Google, Exponent and Tilde. As can be read in the official announcement, its purpose is to solve a handful of problems that these teams faced with npm, namely:

  • installing packages wasn’t fast/consistent enough, and
  • there were security concerns, as npm allows packages to run code on installation.

But, don’t be alarmed! This is not an attempt to replace npm completely. Yarn is only a new CLI client that fetches modules from the npm registry. Nothing about the registry itself will change — you’ll still be able to fetch and publish packages as normal.

Should everyone jump aboard the Yarn hype train now? Chances are you never encountered these problems with npm. In this article, we’re going to compare npm and Yarn, so you can decide which is best for you.

Yarn logo

Yarn vs npm: Functional Differences

At a first glance Yarn and npm appear similar. As we peek under the hood though, we realize what makes Yarn different.

The yarn.lock File

In package.json, the file where both npm and Yarn keep track of the project’s dependencies, version numbers aren’t always exact. Instead, you can define a range of versions. This way you can choose a specific major and minor version of a package, but allow npm to install the latest patch that might fix some bugs.

In an ideal world of semantic versioning, patched releases won’t include any breaking changes. This, unfortunately, is not always true. The strategy employed by npm may result into two machines with the same package.json file, having different versions of a package installed, possibly introducing bugs.

To avoid package version mis-matches, an exact installed version is pinned down in a lock file. Every time a module is added, Yarn creates (or updates) a yarn.lock file. This way you can guarantee another machine installs the exact same package, while still having a range of allowed versions defined in package.json.

In npm, the npm shrinkwrap command generates a lock file as well, and npm install reads that file before reading package.json, much like how Yarn reads yarn.lock first. The important difference here is that Yarn always creates and updates yarn.lock, while npm doesn’t create one by default and only updates npm-shrinkwrap.json when it exists.

  1. yarn.lock documentation
  2. npm shrinkwrap documentation

Parallel Installation

Whenever npm or Yarn needs to install a package, it carries out a series of tasks. In npm, these tasks are executed per package and sequentially, meaning it will wait for a package to be fully installed before moving on to the next. Yarn executes these tasks in parallel, increasing performance.

For comparison, I installed the express package using both npm and Yarn without a shrinkwrap/lock file and with a clean cache. This installs 42 packages in total.

  • npm: 9 seconds
  • Yarn: 1.37 seconds

I couldn’t beleive my eyes. Repeating the steps yielded similar results. I then installed the gulp package, resulting in 195 dependencies.

  • npm: 11 seconds
  • Yarn: 7.81 seconds

It seems the difference closely depends on the amount of packages that are being installed. Either way, Yarn is consistently faster.

Cleaner Output

By default npm is very verbose. For example, it recursively lists all installed packages when running npm install <package>. Yarn on the other hand, isn’t verbose at all. When details can be obtained via other commands, it lists significantly less information with appropriate emojis (unless you’re on Windows).

The output of the "yarn install" command

Yarn vs npm: CLI Differences

Other than some functional differences, Yarn also has different commands. Some npm commands were removed, others modified and a couple of interesting commands were added.

yarn global

Unlike npm, where global operations are performed using the -g or --global flag, Yarn commands need to be prefixed with global. Just like npm, project-specific dependencies shouldn’t need to be installed globally.

The global prefix only works for yarn add, yarn bin, yarn ls and yarn remove. With the exception of yarn add, these commands are identical to their npm equivalent.

  1. yarn global documentation

yarn install

The npm install command will install dependencies from the package.json file and allows you to add new packages. yarn install only installs the dependencies listed in yarn.lock or package.json, in that order.

  1. yarn install documentation
  2. npm install documentation

yarn add [–dev]

Similar to npm install <package>, yarn add <package> allows you to add and install a dependency. As the name of the command implies, it adds a dependency, meaning it automatically saves a reference to the package in the package.json file, just as npm’s --save flag does. Yarn’s --dev flag adds the package as a developer dependency, like npm’s --save-dev flag.

  1. yarn add documentation
  2. npm install documentation

yarn licenses [ls|generate-disclaimer]

At the time of writing, no npm equivalent is available. yarn licenses ls lists the licenses of all installed packages. yarn licenses generate-disclaimer generates a disclaimer containing the contents of all licenses of all packages. Some licenses state that you must include the project’s license in your project, making this a rather useful tool to do that.

  1. yarn licenses documentation

yarn why

This command peeks into the dependency graph and figures out why given package is installed in your project. Perhaps you explicitly added it, perhaps it’s a dependency of a package you installed. yarn why helps you figure that out.

  1. yarn why documentation

yarn upgrade [package]

This command upgrades packages to the latest version conforming to the version rules set in package.json and recreates yarn.lock. This is similar to npm update.

Interestingly, when specifying a package, it updates that package to latest release and updates the tag defined in package.json. This means this command might update packages to a new major release.

  1. yarn upgrade documentation

yarn generate-lock-entry

The yarn generate-lock-entry command generates a yarn.lock file based on the dependencies set in package.json. This is similar to npm shrinkwrap. This command should be used with caution, as the lock file is generated and updated automatically when adding and upgrading dependencies via yarn add and yarn upgrade.

  1. yarn generate-lock-entry documentation
  2. npm shrinkwrap documentation

Stability and Reliability

Could the Yarn hype train become derailed? It did receive a lot of issue reports the first day it was released into the public, but the rate of resolved issues is also astounding. Both indicate that the community is working hard to find and remove bugs. Looking at the number and type of issues, Yarn appears stable for most users, but might not yet be suitable for edge cases.

Note that although a package manager is probably vital for your project, it is just a package manager. If something goes wrong, reinstaling packages shouldn’t be difficult, and nor is reverting back to npm.

The Future

Perhaps you’re aware of the history between Node.js and io.js. To recap: io.js was a fork of Node.js, created by some core contributors after some disagreement over the project’s governance. Instead, io.js chose an open governance. In less than a year, both teams came to an agreement, io.js was merged back into Node.js, and the former was discontinued. Regardless of the rights or wrongs, this introduced a lot of great features into Node.js.

I’m seeing similar patterns with npm and Yarn. Although Yarn isn’t a fork, it improves several flaws npm has. Wouldn’t it be cool if npm learned from this and asked Facebook, Google and the other Yarn contributors to help improve npm instead? Although it is way too early to say if this will happen, I hope it will.

Either way, Yarn’s future looks bright. The community appears excited and is receiving this new package manager well. Unfortunately, no road map is available, so I am not sure what surprises Yarn has in store for us.

Conclusion

Yarn scores points with way better defaults compared to npm. We get a lockfile for free, installing packages is blazing fast and they are automatically stored in package.json. The impact of installing and using Yarn is also minimal. You can try it on just one project, and see if it works for you or not. This makes Yarn a perfect drop-in substitute for npm.

I would definitely recommend trying Yarn on a single project sooner or later. If you are cautious about installing and using new software, give it a couple of months. After all, npm is battle-tested, and that is definitely worth something in the world of software development.

If you happen to find yourself waiting for npm to finish installing packages, that might be the perfect moment to read the migration guide ;)

What do you think? Are you using Yarn already? Are you willing to give it a try? Or is this just contributing to the further fragmentation of an already fragmented ecosystem? Let me know in the comments below.

  • http://reve.lt Roy Reveltas

    Ahem, there’s a typo, “beleive”. Please fix.

    • James Hibbard

      Thanks, fixed.

      • Mikel Kew

        Another typo: “..reinstaling packages..”

  • Kaan Özcan

    If at any point yarn introduces local repositories. Saves us from the incompetence of “npm link”. Manages development, snapshot, alpha releases.I am switching to yarn.

  • Sileghem Thomas

    `npm update` updates packages to their latest version while still satisfying the package.json requirements

    so `npm update` === `rm -rf node_modules && npm install` === `yarn upgrade`

    • Leonardo Kewitz

      Exactly. This also means that “which updates packages to their latest version.” isn’t quite correct.
      Supposing your packages were installed using “install –save” (that uses caret ranges on the package.json) and that package has a new major version, you won’t be able to update to the latest version per se.

      • Gábor Farkas

        Does `npm update` really delete the node_modules directory? It occured to me in many cases that packages that are no longer referred in the package.json remain in the node_modules directory (thus I cannot make really sure that what works on my environment, will work for another developer after a clean install)

        • Leonardo Kewitz

          No. He was referencing the way it works related to the version and packages that are installed. The NPM update will not remove anything, you need to use `npm un|uninstall`.
          The best way to make sure that all versions match across multiple environment is using shrinkwrap, which will actually fail if you have something installed that is not listed on packages.json.

  • Senator

    Who cares if you care or not?

  • https://github.com/julmot Julian Motz

    I personally miss the mention of the Bower CLI in comparison to yarn.

  • Mike Haughton

    It’s called giving credit where credit is due.

  • Matt Morris

    Another typo that might be confusing for some people: “…the file where both npm as Yarn keep track…” should be “…the file where both npm and Yarn keep track…” I believe (“as” -> “and”). Thanks for the article!

  • Max Heiber

    Regarding your idea for the Yarn contributors to improve the npm CLI itself, rather than maintain a separate project:

    In this podcast episode, the creators of Yarn explain why they created a separate project:
    https://javascriptair.com/episodes/2016-11-02-bonus/

    Main reasons:
    – npm CLI is more backwards-compatible than Yarn. Being *not* backwards-compatible makes the Yarn codebase easier to work with. This backwards-incompatibility also means there is a place for npm CLI for years to come (probably).
    – The parts of npm CLI that caused problems for them went deep into the architecture, so that starting from scratch was easier than forking

  • naveen

    Ahem nice post🐼

  • https://www.xgqfrms.xyz xgqfrms

    Yarn vs npm ???

    why not support insert pictures ???

  • mritzp

    Can you elaborate on why you think generating checksums would help in a “left-pad” scenario? I would assume that if a module gets unpublished, it is lost irrespective of whether its binary content was hashed or not.

    • http://www.nicholasjohnson.com/ Nick Johnson

      As I understand it, it means that the package you thought was getting installed is actually the package that gets installed, not a different codebase with the same name and version number.

      In theory, the NPM repository guards against this, since NPM requires a new version number per upload, but after left-pad people might be reluctant to rely on NPM for their package security.

      As you say, it won’t prevent a build from failing if a package is removed.

  • Lucas Antoine

    You forgot to mention that yarn is just a package manager and doesn”t allow publishing on the npm repo.
    Ok it is faster, but limited, this is not a replacement, just a tool to allow offline npm installs out of the box.
    Too much opinionated, A vs B should never hold an opinion.

  • http://www.nicholasjohnson.com/ Nick Johnson

    Vildan is a core team member at Aurelia. The others have written pretty decent articles. Perhaps you were expecting Bill Gates and Linus Torvalds?

Recommended
Sponsors
Get the latest in JavaScript, once a week, for free.