Yarn vs npm: Everything You Need to Know
In this tutorial, we’ll compare Yarn vs npm — the two most popular package managers. We’ll set them side by side and explore their respective benefits and disadvantages to help you choose which one to use for your projects.
Laying Out the Basics
Back in the good old days, a simple text editor was enough for developers to create and manage the large part of their projects. But since then, the Web has changed drastically. Nowadays, it’s common for even a fairly simple project to have hundreds or thousands of scripts, with complex nested dependencies, which are simply impossible to manage without some kind of automated tool. And this is the place where package managers come into play.
A package manager is a tool that automatically handles a project’s dependencies in a variety of ways. For example, with the help of a package manager we can install, uninstall, update, and upgrade packages, configure project settings, run scripts, and so on. All the hard and tedious work is done by the package manager, leaving to us only the fun part — the coding itself.
npm stands for Node Package Manager. It was released back in 2010, beginning a new era in web development. Until then, the project dependencies were downloaded and managed manually. npm was the magic wand that pushed the Web to the next level.
npm actually involves three things:
- a website for managing various aspects of your npm experience
- a registry for accessing an extensive public database of JavaScript packages
- a command-line interface (CLI) for interacting with npm via the terminal
However, when most people talk about npm, they usually mean the last one — the CLI tool. It ships as a default package manager with each fresh Node installation. This means you can start using it right away.
If you’d like a deep dive into working with npm, please consult our Node Package Manager Guide.
Yarn stands for Yet Another Resource Negotiator. The Yarn package manager is an alternative to npm, released by Facebook in October 2016. The original goal of Yarn was to deal with npm drawbacks, such as performance and security issues. Yarn was quickly positioned as a safe, fast, and reliable JavaScript dependency management tool.
But the npm team learned their lesson and rapidly filled the npm gaps by implementing the missing features.
Let’s quickly travel through time to see the big picture:
- 2010: npm is released with support for Node.
- 2016: Yarn is released. It shows much greater performance than npm. It also generate a
yarn.lock
file that makes sharing and exact replication of repos much easier and predictable. - 2017: npm 5 is released. It offers auto-generation of a
package-lock.json
file in answer toyarn.lock
. - 2018: npm 6 is released with improved security. Now npm checks security vulnerabilities before dependencies are installed.
- 2020: Yarn 2 and npm 7 are released. Both packages come with great new features, as we’ll see later in this tutorial.
- 2021: Yarn 3 is released with various improvements.
Nowadays, both package managers are neck and neck in the package management race, offering similar features and capabilities. But there are still several differences that help to determine which we choose to use.
In the rest of this tutorial, we’ll explore the main similarities and differences between npm and Yarn.
Yarn vs npm: an Installation Comparison
We’ll start our comparison exploration with the installation process for both npm and Yarn.
Installing the package managers themselves
As I noted above, npm comes preinstalled with Node, so there’s no need to install npm manually.
In contrast, Yarn needs to be installed explicitly. First, we need to install Yarn globally:
npm install -g yarn
Then, we can use it on a per-project basis by setting the desired version inside our project. We do that by running the yarn set version
command in the project’s root directory:
yarn set version berry
In this case, berry
is the version we want to set.
If we want to update to the latest version, we run this:
yarn set version latest
With Yarn we can use a different version for each project.
To do the same with npm, you’ll need to have nvm (Node Version Manager) installed. Here’s how to install multiple versions of Node using nvm.
Installing project dependencies
Now, let’s see how project dependencies are installed.
When we run npm install
, the dependencies are installed sequentially, one after another. The output logs in the terminal are informative but a bit hard to read.
To install the packages with Yarn, we run the yarn
command. Yarn installs packages in parallel, which is one of the reasons it’s quicker than npm. If you’re using Yarn 1, you’ll see that the yarn output logs are clean, visually distinguishable and brief. They’re also ordered in a tree form for easy comprehension. But this is changed in versions 2 and 3, where the logs aren’t so intuitive and human-readable.
So far, we’ve seen that npm and Yarn have different commands for installing packages. In the next section, we’ll explore more commands.
Comparing npm and Yarn Commands
npm and Yarn share many commands, but there are also many non-identical commands. Let’s first explore some of the identical commands:
npm init
|yarn init
: create a new packagenpm run
|yarn run
: run a script defined in thepackage.json
npm test
|yarn test
: test a packagenpm publish
|yarn publish
: publish a packagenpm cache clean
|yarn cache clean
: remove all data from the cache folder
These commands make switching between two managers easy, but there are some non-identical commands that can cause confusion. Let’s see what they are in the next list:
npm install
|yarn
: install dependenciesnpm install [package]
|yarn add [package]
: install a packagenpm install --save-dev [package]
|yarn add - -dev [package]
: install a package as a development dependencynpm uninstall [package]
|yarn remove [package]
: uninstall a packagenpm uninstall --save-dev [package]
|yarn remove [package]
: uninstall a development dependency packagenpm update
|yarn upgrade
: update the dependenciesnpm update [package]
|yarn upgrade [package]
: update a package
Yarn has also some unique commands which don’t have npm equivalents. For example, the why
command displays the reason why a package is needed: it may be a dependency, a native module, or a project dependency.
Yarn vs npm: Speed and Performance
Whenever Yarn or npm need to install a package, they carry 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. In contrast, Yarn executes these tasks in parallel, increasing performance.
While both managers offers caching mechanisms, Yarn seems to do it a bit better. By implementing a zero-install paradigm, as we’ll see in the features comparison section, it’s capable of installing packages almost in no time. It caches every package and saves it on the disk, so in the next installation of this package you don’t even need to have an internet connection, because the package is installed offline from the disk.
Even though Yarn has some advantages, the speeds of Yarn and npm, in their last versions, are pretty comparable. So we can’t define a clean winner here.
Yarn vs npm: a Security Comparison
One of the main criticisms of npm is regarding security. Previous npm versions have a couple of serious security vulnerabilities.
As of version 6, npm audits packages during installation and tells you if any vulnerabilities are found. We can do this check manually by running npm audit
against the installed packages. If any vulnerabilities are found, npm will give us security recommendations.
As you can see in the screenshot above, we can run npm audit fix
to fix package vulnerabilities, and the dependency trees will be fixed if it’s possible to do so.
Both Yarn and npm use cryptographic hash algorithms to ensure the integrity of the packages.
Yarn vs npm: a Feature Comparison
Just as with commands, some features are shared by npm and Yarn, while there are also some differences. Let’s first explore the common features these two package managers share.
Generating a 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. But unfortunately, this isn’t always the case. The strategy employed by npm may result in two machines ending up with the same package.json
file, but having different versions of a package installed — which will possibly introduce bugs.
To avoid package version mismatches, an exact installed version is pinned down in a package lock file. Every time a module is added, npm and Yarn create (or update) a package-lock.json
and yarn.lock
file respectively. This way, you can guarantee another machine installs the exact same package, while still having a range of allowed versions defined in package.json
.
Using workspaces
Workspaces allow you to have one monorepo to manage the dependencies across multiple projects. This means you have a single, top-level root package that has multiple child packages called workspaces.
Running scripts remotely
The npx
command is used to run scripts from ./node_modules/.bin
. It also allows you to execute packages from the npm registry without installing them in your project dependencies. For example, you can create a new React app by running the following:
npx create-react-app my-app
In Yarn, you can achieve the same result by using the equivalent dlx
command:
yarn dlx create-react-app my-app
The rest of the features we’re going to explore are unique to Yarn.
Zero installs
Zero installs store the cache in your project directory, in a .yarn
folder. When you use commands such as yarn
or yarn add <package>
, Yarn will create a .pnp.cjs
file. This file contains a dependency hierarchy used by Node to load your project packages. Thus, you can access them almost at zero time.
Plug’n’Play
Plug’n’Play is an alternative installation strategy. Instead of generating a node_modules
directory and leaving the resolution to Node, Yarn generates a single .pnp.cjs
file that maps packages to their location on the disk and to their list of dependencies. This feature can lead to faster project startup, better optimized dependency tree, faster installation time, and of course removes the need for a node_modules
folder.
Licenses
Yarn is packed with a built-in license checker that can be useful in different scenarios when you’re developing applications.
Yarn vs npm: Which Package Manager to Choose
We’ve covered the various similarities and differences of npm and Yarn, but we haven’t established which is better and which one we should choose. As ever, the answer depends on our desires and requirements.
As a general guide, let me conclude with the following advice:
-
Choose npm if you’re happy with your current workflow, you don’t want to install an additional tool, and you don’t have a lot of disk space.
-
Choose Yarn if you want some great features such as Plug’n’Play, you need some functionality that’s missing in npm, and you have enough disk space.
If you still find it hard to make a clear decision between npm and Yarn, then you can check pnpm, which tries to combine the best from both package managers and is the third big fish in the package management pool.
Yarn vs npm: Conclusion
We’ve seen how important package managers are for modern web development, and we’ve compared the two most popular rivals on the market. They both have their advantages and shortcomings, and in order to choose the best for you, you need to have a clear idea of your requirements. The best way to decide which is more suitable for you is to try them both and see which performs better.
And finally, don’t overthink it. Just choose one and move to the fun part: creating great apps!