NPM vs. Yarn: Which Package Manager Should You Choose?

NPM vs. Yarn
Table of Contents

Developers often find themselves in a dilemma when trying to select the best package managers for building, using, reusing, managing, and sharing packages with others.

Two of the most popular package managers among JavaScript (and Node.js) developers are npm and Yarn. There seems to be a lot of similarities between these two package managers—since Yarn drew a lot of inspiration from npm, and now npm seems to be drawing inspiration from Yarn. However, there are subtle differences between them, which can make you prefer one over the other. 

We’ll be comparing these two side by side so that you can make the right decision on the one to go for when working on your projects.

Before we start comparing them in detail, let’s get some background information that will assist in this npm vs. Yarn debate.

What is npm?

npm (short for Node Package Manager), initially released in 2010, is a tremendously popular package manager among JavaScript developers. It is the default package that is automatically installed whenever you install Node.js on your system.

It consists of three components: the website to manage various aspects of your npm experience, Command Line Interface (CLI) to interact with npm via the terminal, and registry to access an extensive public database of JavaScript software. 

What is Yarn?

Yarn, initially released by Facebook in 2016, is another popular package manager for the JavaScript programming language. The intention behind creating Yarn was to address some of the performance and security shortcomings of working with npm (at that time).

Since then, npm has undergone several improvements to fix some of its inefficiencies. As a result, as we’ll demonstrate in this blog post, npm and Yarn are now in a neck-to-neck race over which package manager trumps the other.

In an attempt to take Yarn a notch higher, the core team behind its development released Yarn 2 in January 2020. While Yarn 2 brings several improvements on the table, it has been heavily criticized among the developer community, and even Facebook engineers have publicly washed their hands from using it.

So, for the rest of this article, we’ll be discussing Yarn 1, and simply referring to it as Yarn, unless explicitly stated otherwise.

Let’s now compare Yarn vs. npm similarities and differences.

Comparing Yarn vs. npm similarities and differences

1. Popularity

Choosing a technology that is widely adopted can assist you in getting help faster when experiencing any implementation challenges. While Yarn is newer as compared to npm, it seems to be catching up quickly in popularity.

For example, if we compare the number of downloads between npm and Yarn in the past 5 years, we can see that npm is the clear winner here. 

However, if we use the extent of their GitHub activity to compare the popularity of the two tools, we notice a totally different story.

For npm:

For Yarn:

As you can see on the above screenshot, taken on August 6th, 2020, Yarn, with nearly 12 times the stars and 3 times the forks, maybe holding the lead.

2. Installation

Installing npm seems much easier than that of Yarn—npm comes already bundled with your Node.js installation, so there’ll be no need to install it.

Yarn is available as an npm package. So, you can simply install it by running the following command on the terminal:

npm install yarn

You can also opt for other options to install Yarn.

3. Managing dependencies

However, the Yarn core team does not recommend installing it via npm. Depending on your system requirements, you can go for any of these installation options.

Yarn and npm have more or less similar ways of managing dependencies. They both provide the package.json file that exists at the root of the project’s working directory. This file keeps all the relevant metadata associated with the project. It assists in managing the project’s dependencies version, scripts, and more.

Both the package managers store dependency files into the node_modules folder. However, in Yarn 2, the folder will no longer be supported, by default.

Furthermore, both Yarn and npm provide an autogenerated lock file that has the entries of the exact versions of the dependencies used in the project. 

In Yarn, it is called yarn.lock while in npm, it is called package-lock.json. As the name implies, this file locks the dependencies to their stipulated versions during the installation process, after establishing the versioning parameters in the package.json file. 

When installing a dependency, the lock file ensures the same file structure in node_modules is maintained across all environments. This provides determinism, supports collaboration with other developers, and prevents code breakages from installing new or incompatible dependencies.

Whereas Yarn included the lock file feature in its first version, npm tried to overcome this shortcoming and introduced it later in version 5 (May 2017). 

While Yarn and npm follow a similar style of managing dependencies, it’s advised not to use them together, unless they are pointed at different registries from their default installations. If used together, they can create conflicts, particularly due to resolution inconsistencies arising from unsynchronized lock files.

Nonetheless, Yarn recently announced a new feature that increases the awareness between the two package managers and allows developers to transition from npm to Yarn smoothly.

This feature allows developers to import and install dependencies from the npm’s package-lock.json file. It is a useful improvement, especially for those in mixed yarn/npm environments or intending to migrate their existing projects to Yarn. 

To use this feature, just run the yarn import command in a repository having the package-lock.json file. As a result, Yarn will apply the resolution parameters in the package-lock.json file to generate a corresponding yarn.lock file.

Similarly, npm is also working to enable developers to play nicer with Yarn. In the upcoming v7, npm will make updates to the package-lock.json file to allow the handling of yarn.lock files. This will reduce the friction often experienced when switching between npm and Yarn (or using both).

4. Performance

The performance of your package manager is an important consideration when managing a large number of packages. Since development is arduous, you need a performant tool that will not weigh you down.

As earlier mentioned, one of the main reasons why Yarn was developed was to overcome the performance issues with npm. So, initially, Yarn was the clear winner in terms of performance.

However, in recent times, especially from v5 and v6, npm has been considerably bridging the gap with Yarn. While Yarn is still faster in most cases, npm is quickly tightening this competition.

Several benchmark tests have been done to compare the speed of these two stacks. For example, here is a table that summarizes the results of one test that compared the speed of installing some simple dependencies under different conditions:

As you can see above, Yarn clearly trumped npm in performance speed. During the installation process, Yarn installs multiple packages at once as contrasted to npm that installs each one at a time.

Reinstallation was also pretty fast when using Yarn. It’s because of its offline mode feature that uses a caching mechanism to allow for fast download of previously downloaded packages. While npm also supports the cache functionality, it seems Yarn’s is far much better.

5. Security

Security is another serious bone of contention when performing a Yarn vs. npm review. While Yarn was initially regarded to be more secure, the npm team has made commendable comebacks with the introduction of significant security improvements.

With npm v6, security is built-in. If you try installing code with a known security vulnerability, npm will automatically issue a warning. Also, a new command, npm audit, has been introduced to assist you in recursively assessing your dependency tree to identify anomalies. 

On the other hand, some of Yarn’s exciting security features include using checksum to verify the integrity of every package and the ability to check licenses of your installed packages.

6. Updating 

Performing an upgrade to the latest package version available is similar in both tools, albeit with some CLI command differences.

Here is how to update Yarn dependencies

yarn upgrade
yarn upgrade [package-name]

Here is how to update npm dependencies

npm update
npm update [package-name]

In both tools, if you do not indicate a package name, all the project’s dependencies will be updated to their latest version. This will be based on the version ranges defined in the package.json file. Also, the package-lock.json file or the yarn.lock file will be modified, based on the tool you’re using.

On the other hand, if you indicate a package name, only the specified package will be updated.

7. CLI commands

Developers usually spend a lot of time interfacing with terminals; it’s where they live. Therefore, another vital point for comparison is the CLI. 

Let’s look at some commands common to both tools:

Let’s look at some commands different in both tools:

Let’s look at some commands present in one tool but absent in another:

In terms of the output of running the CLI commands, Yarn delivers a cleaner output (that also comes with emojis, unless you’re on Windows). 

For example, here is a screenshot of running a simple install command using both tools:

For Yarn:

For npm:

As you can see above, npm generates a lot of noise, by default. On the contrary, Yarn’s output is cleaner and less verbose. 

8. Lifecycle scripts

Both npm and Yarn support lifecycle scripts. These are entries in the scripts property of the package.json file that let you define various commands you can use to automate tasks related to your package. Lifecycle scripts greatly ease the lives of developers, especially in automating repetitive tasks.

Here is an example:

{
  "name": "mypackage",
  "scripts": {
    "myexample": "echo 'hello world'"
  }
}

To execute it using npm, run the following

npm run myexample

To execute it using Yarn, run the following:

yarn run myexample

The difference seems to lie in how npm and Yarn support pre and post hooks. These are commands that run before or after a script lifecycle event.

Here is an example:

"scripts": {
   "prebuild": "one",
   "build": "two",
   "postbuild": "three",
   "test": "jest"
}

In the above code, the commands prefixed with pre and post will be executed in their respective order.

In npm, you can use pre and post commands for a number of built-in and arbitrary scripts specified in the scripts field of the package.json file. Yarn 1 also lets you use the commands to define scripts. 

However, Yarn 2 does not support each lifecycle script initially present in npm. That intentional decision is based on realizing that including several lifecycle scripts in a project often leads to avoidable confusion and errors. 

Furthermore, Yarn 2 does not support arbitrary pre and post commands for user-specified scripts. For example, it does not support using prestart. The Yarn 2 team has observed that the behavior, which was inherited from npm, resulted in scripts running implicitly, instead of explicitly. As a result, it muddles the normal execution flow and ignites surprising executions, such as yarn serve also being executed as yarn preserve

Conclusion

Both Yarn and npm are useful tools for ensuring your project’s dependencies are under control. While npm was introduced first, Yarn has quickly gained traction in the JavaScript world.

Yarn drew a lot of inspiration from npm, especially by using its shortcomings to create a package management solution that developers would love. Likewise, npm’s core team has continued to punch back with every new release—updating its features to meet the needs of developers. 

So, presently, we can see that the two package managers are closer together in terms of functionalities, almost reaching feature parity. Nonetheless, there are a few twists and turns that can make you opt for one over the other. 

Ultimately, your choice between npm vs. Yarn will depend on your requirements, tastes, and preferences. 

Happy coding!


Are you letting open-source vulnerabilities go undetected?

Mend Bolt is a powerful free extension that operates in real-time to provide visibility over your open source components within Azure Pipelines or GitHub.

  • Get real-time alerts on security vulnerabilities
  • Ensure the license compliance of open source components.
  • Receive automated open-source inventory reports for every build or project.

Get it now and join thousands of developers who’ve already gained full visibility over their open-source components.

Recent resources

What is LDAP Injection? Types, Examples and How to Prevent It

Learn what LDAP Injection is, its types, examples, and how to prevent it. Secure your applications against LDAP attacks.

Read more

How to Use Dependency Injection in Java: Tutorial with Examples

Learn how to use Dependency Injection in Java with this comprehensive tutorial. Discover its benefits, types, and practical examples.

Read more

Idempotency: The Microservices Architect’s Shield Against Chaos

Discover the power of idempotency in microservices architecture. Learn how to maintain data consistency and predictability.

Read more