Photo by Mika Baumeister on Unsplash

NPM vs Yarn

Jonathan Reeves
8 min readJul 9, 2021

Hello again. I wanted to try to shed some light on the NPM vs Yarn debate. I have used both extensively over the years. Depending on the project that I was building both NPM and Yarn have been extremely helpful in managing the setup of my project as well as the packages used. I am a fan of both as I believe that both of them offer different experiences depending on the type of project you are working on. In this post I want to walk you through using both to set up your project and then you can decide which one you want to use going forward.

NPM

NPM, also known as the node package manager, is a tool that comes preinstalled with Node. It is the default package manager for installing the various JavaScript libraries to use within your projects. I typically use NPM when I am creating an API using Node. It is typically the default choice for most developers when it comes to creating an API using Node or quite possibly Nest.js. (This post will not go into creating an API or using Nest.)

Typically the argument about whether to use NPM or Yarn stems from the fact that Yarn was created in order to bring a package manager to React or frontend (client side) code. Yarn for a long time was faster than NPM. You could install a package using Yarn in say less than 1ms whereas at the time NPM would take 1.2ms or above. Which when you are waiting for a package to install in order to use it in your project it can take a little bit. It can also be frustrating having to wait so long to make sure that it installed correctly. Some will still say that Yarn is faster and NPM is complete trash. I disagree with these statement wholeheartedly. While I love Yarn I also enjoy using NPM. Let’s set up a project using NPM and see how long it takes from initializing the project to installing a package. I am not going to go over how to install Node and NPM in this article as I am making an assumption that you already have at least Node installed which by default has NPM.

Setting Up The Project

Ok let’s open up our terminal and navigate to a place to store our projects. Follow these steps:

$ cd Desktop && mkdir npmVsYarn && cd npmVsYarn
$ mkdir npmHello
$ cd npmHello
$ npm init -y
$ npm install chalk@2.4 boxen@4.0
$ mkdir bin
$ touch bin/index.js
$ cd ..
$ code .

In the above commands we are navigating to our Desktop, making a new directory (mkdir) named npmVsYarn, changing in to it (cd). Then we are making another directory called npmHello. This directory will store our npm project. We are going to build a simple CLI tool using npm here. Next we install the chalk and boxen libraries. Below is a snippet of the time it took.

Image of my terminal after it installed the npm packages

After everything has been installed and the directories and files created we should see the below image.

Our current directory after initial setup

I am using VS Code, if you are using another editor yours might like slightly different however you should have a bin folder with an index.js file inside. The node_modules folder which stores all the packages for the project. Both a package-lock.json and package.json file for project setup and distribution. I am not going to go into detail on what the package-lock.json file does or how it relates to the package.json file here in this post.

Now that the project is open in our editor of choice we can start writing the code for the project. Open up index.js and type:

#!/usr/bin/env nodeconst chalk = require("chalk");
const boxen = require("boxen");
const greeting = chalk.green.bold("Hello with NPM!");const boxenOptions = {
padding: 1,
margin: 1,
borderStyle: "round",
borderColor": "#006847",
backgroundColor: "#111111"
};
const msgBox = boxen(greeting, boxenOptions);
console.log(msgBox);

Next we will open up the package.json file and input the following:

{
"name": "npmHello",
"version": "1.0.0",
"description": "",
"main": "bin/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "Jonathan Reeves",
"license": "MIT",
"bin": {
"hello": "./bin/index.js"
}
}

We will run the install command for our script so we can run this globally.

npm install -g .

This will allow us to run

hello

If you don’t want to install the package to use globally you can run the command:

node . // runs the project directly from the current directory

The above command, like the comment suggest, runs the project directly from the current directory the project exists in instead of having you install the package as though you are pulling it from npm directly.

We should now see our hello message appear in our terminal like this:

Hello message displayed in terminal

I chose the colors green since those are the colors typically synonymous with Node and npm. Feel free to look at the chalk documentation for the various colors you can use.

That’s it. Pretty simple. I feel like this gives a good example of the commands that npm uses. In the next section we will create the same project using Yarn.

Yarn

Now Yarn is the de facto package manager for React. It was developed by the React team so it makes sense as far as why this is the default package manager. Yarn was created because of the problems that the Facebook engineers ran into when trying to scale npm. I won’t go into all the details of why since it’s really not that important. However most users new to JavaScript don’t have Yarn installed. It doesn’t come preinstalled with Node like NPM does. In order to use Yarn we have to use NPM to install it. I use a different tool for handling my installs for Node, NPM and Yarn called Volta but I will cover the steps on how to install Yarn the more “traditional” way so-to-speak. If interested in Volta you can visit here.

$ npm install --global yarn
// or you can use
$ npm i -g yarn

Both commands do the same thing. The bottom one is just the shorthand for installing it. If you’ve used npm a lot before this you are most likely familiar with the second way as its much faster to type out.

Initialize The Project

Similar to the npm project before we are going to do similar steps. Let’s get started. Follow these commands:

$ cd ..
$ mkdir yarnHello && cd yarnHello
$ mkdir bin && touch bin/index.js
$ yarn init -y
$ yarn add chalk boxen

Here is the output from Yarn installing the packages

Results from Yarn adding packages

Our directory should now look like the following inside of our editor:

Current directory with the newly added yarnHello project

First let’s start by updating our package.json file like we did with the previous project.

package.json

"name": "yarn-hello",
"version": "1.0.0",
"main": "bin/index.js",
"license": "MIT",
"bin": {
"hello": "./bin/index.js"
},

After updating the main property and adding the bin command our package.json should look like above. Right away you will probably notice that the package.json from yarn init looks a bit differently than the one from our npm init. We are missing a few options. Those options aren’t necessary for the app to work and since we don’t necessarily publish yarn projects to npm they aren’t really needed. In order to publish to npm though you will need to add them later if you choose. Since npm does have a repository that you can upload your packages to it adds those “fields” for you and if you don’t add the -y flag to your command when initializing the project with npm will ask you about them. Those additional fields are:

"description: "",
"keywords": [],
"author: ""

Also notice that with the Yarn project the license is set to MIT and with the NPM project it is set to ISC. It is up to you which license you use. That goes beyond the scope of this article I just wanted to point out differences that are common between using the two.

Creating Our Message

Now open up the index.js and we will add the following code:

#!/usr/bin/env nodeconst chalk = require("chalk");const boxen = require("boxen");const greeting = chalk.cyanBright.bold("Hello with Yarn!");const boxenOptions = {
padding: 1,
margin: 1,
borderStyle: "singleDouble",
borderColor: "#7BAFD4",
backgroundColor: "#8D9092"
};
const msgBox = boxen(greeting, boxenOptions);console.log(msgBox);

Just like we did before we created our message but this time I decided to make the colors more in line of React since Yarn is typically used in more React development. As you can see both npm and yarn require node to handle running the application so nothing changes there. But there are a few differences in how you install packages to your project when using Yarn over NPM and vice versa. Let’s take a look at our output:

Result from running project

That’s it for this one as well. We now have our working CLI tools from using both NPM and Yarn to install the dependencies. Below is a list of the common commands used in both NPM and Yarn. I hope this helps

Common Commands to Run

I am going to list out the most common commands in NPM first and then the equivalent in Yarn.

$ npm init or yarn init // creates a package.json file and adds it to the project.$ npm install or yarn // installs the dependencies listed in the pakcage.json into a local node_modules folder.$ npm install package-name or yarn add new-package // installs a specific package to our project as well as includes it as a dependency inside package.json. Dependencies are packages needed when we run our code.$ npm install --dev or yarn add new-package --dev // will install a specific package to our project as well as include it as a development dependency in package.json. Development dependencies are packages needed only during the development workflow. They are not needed for running the application in production.npm install --global or yarn global add new-package // will install the package globally, rather than locally to a specific project. This is really only used when you need to run something not tailored for your specific project.

Conclusion

Both of these tools are very handy. Depending on what your project is you might want to choose one over the other. I hope that you enjoyed this article and building out some simple CLI projects. We won’t call them tools since they don’t really help with anything. One thing I want to point out is that regardless of which package manager you choose to go with the underlying thing to keep in mind is the code you write is the same JavaScript for both. The only difference is the minute speed increase one has over the other.

--

--

Jonathan Reeves
Jonathan Reeves

Written by Jonathan Reeves

I am a software engineer that is currently trying to break into the DevOps world using Python. Professionally I use JavaScript with React to build websites.

No responses yet