Software Development

NPM vs. YARN vs. PNPM

February 4, 2020

In today’s post, as we approach the end of the first quarter of 2020, we will be examining what npm, YARN, and Pnpm are, their working logic, and their differences.

What are NPM, PNPM, and YARN?

All three of npm, Pnpm, and Yarn are Package Managers. So, what is this Package Manager? What does it do? It is a tool widely used by developers to share tools, install various modules, and manage the dependencies of these modules.

Modules and dependencies;

  • Are added to projects automatically or manually
  • Are deleted from the added project
  • Are kept on record in a specific file
  • Are updated by checking their versions

In general, all three are managed via the command line.

NPM

Even though I had to write NPM in the title, it is a package manager accepted as a standard by Node.js, written entirely in JavaScript as a camelCase abbreviation of Node Package Manager, and thus known as npm, which allows the management of softwares / modules / packages.

To be able to use npm, Node.js must absolutely be installed on your system first. To check whether Node.js and npm are present on your system, you can run the following commands.

node -v
npm -v

If these commands return a version as a response, it means these tools are available on your system.

Package.json

It is a local package database containing information about the packages / modules and dependencies used in the project where it is located. When starting a project, you can create it yourself (with a specific syntax), or it can be created using npm with the init command. In installations done with npm init, the tool will ask you a series of questions and create the file accordingly. If you are going to start a new project with a boilerplate like React Native CLI, package.json will be formed as prepared in the CLI as a result of the CLI’s init process.

Package Installations

  • Global Installation transfers modules into {prefix}/lib/node_modules, executable files into {prefix}/bin, and man files into {prefix}/share/man. {prefix} usually corresponds to the /usr/local directory.

The installation has the path /usr/local/lib/node_modules/express. When we handle global installation with --save-dev, the relevant definition will also be added to the package.json file as devDependencies.

  • Local Installation installs modules into the working directory (project directory). Generally, the installation is carried out by creating a node_modules folder. Executable files are also kept inside this folder under the ./node_modules/.bin/ path. man files are not processed in local installation.

mkdir newproject
cd newproject
npm init -y
npm install express

Following the execution of the command, the node_modules folder will be created in the newproject directory and the express package will be installed inside this folder. After this installation, we can access the package from within our application via ../node_modules/express.

Dependencies

Dependencies is the area where package information will be added when the --save flag is defined along with the install command during installation. These packages are required for production. devDependencies, on the other hand, is the place where the details of the packages will be added with --save-dev. The packages kept here are required for development and testing.

YARN

Yarn is a package manager developed as an alternative to npm under the leadership of Facebook software teams, with the support of Google, Exponent, and Tilde companies.

While it generally supports the features of npm, it has also brought new features to solve the security, consistency, and performance problems that gave Facebook engineers a headache.

Yarn has a structure that caches every installed package, so that the package does not need to be downloaded again, and parallelizes the operations performed to maximize resource utilization.

For Yarn installation, we can use another package manager at the system level. Brew or MacPorts can be preferred for macOS.

brew install yarn
#ya da
sudo port install yarn

Of course, the installation process can also be performed without a package manager. To perform the download operation via curl over the command line, this command can be used:

curl -o- -L https://yarnpkg.com/install.sh | bash

For other download and version usage options, you can examine the Yarn > Installation page.

To create a new project with Yarn, we use the yarn init command. When we execute this command in the directory where the project will be run, some information such as name, version, entry point, repository url is requested from us via prompt. Following the entry or skipping of the information, a package.json file is created..

Package Installations

  • To perform the installation process globally, it is enough to add the global parameter.

yarn add global [paket-adi]

  • When we want to add a new package / dependency to the project directory, we benefit from the yarn add command.

yarn add [paket-adi]
yarn add [paket-adi]@[paket-versiyonu]
yarn add [paket-adi]@[etiket]

  • I mentioned parallelization in the paragraph where I touched upon Yarn features.

yarn add [paket-adi-1] [paket-adi-2] [paket-adi-3] [paket-adi-4]

PNPM

pnpm, which is short for performant npm, is a package manager that has all the features of npm and Yarn and shows better performance in many aspects.

It is claimed to be much faster than both npm and Yarn. You can access the benchmark comparisons here.

It uniquely identifies Node Modules on the system using hard links, and then uses symbolic links (symlinks) inside the node_modules folder of each project; meaning you will now have only a single copy of lodash on your system, for example 🎉. This means an incredible space savings on your disk.

Yarn also considered using symbolic links in the past, but due to several reasons, they made another decision and changed their path. In individual trials, I found the performance of pnpm highly successful and it did not cause any problems.

Since its commands are very similar to Yarn, there was no adjustment problem at all.

You can use the link for all details regarding its usage.

It has a “strictness” feature explained in this link. This feature prevents you from using any module that is not in package.json. This stands out as a great feature that allows you to avoid bugs that are hard to track.

npm install -g pnpm

Since pnpm is a drop-in replacement, you can use all commands valid for npm for pnpm as well.

DIFFERENCES

Speed — Performance

When npm, pnpm, or Yarn needs to install a package, it executes a series of tasks. In npm and pnpm, these tasks are executed per package and sequentially, meaning it waits for a package to be fully installed before moving on to the next. Yarn, on the other hand, improves performance by performing these tasks in parallel.

While the npm tool downloads Node packages sequentially from the central repo, YARN can download multiple packages simultaneously. Thus, it opens the door to faster installations. YARN also has a remote repository named yarnpkg.com.

A package at version a.b.c installed with the YARN tool is additionally stored on your local computer. Thus, when the package at the relevant version is attempted to be downloaded again, it does not need to visit the remote repo.

pnpm creates hard links from the global store to the project’s node_modules folders. Hard links point to the place on the disk where the original files are located. For example, if you have foo as a dependency in your project and it takes up 1MB of space, it will appear to take up 1MB of space in the project’s node_modules folder and the same amount of space in the global store. However, this 1MB is the same space addressed from two different locations on the disk. So the total foo takes up 1MB, not 2MB. Since a new symlink is always created for the same packages, it provides benefits in terms of both speed and disk space.

Consistency

In the Node module system, every package used to have a version. In the versioning format, the semantic versioning method was preferred. As is known, module dependencies were kept in the file named package.json as name and version range.

For example, the amodule below was dependent on version 1.0.0 and above, and 1.0.7 and below of the lemodule module. It couldn’t do without it.

{
“name”: “amodule”,

“dependencies”: {
“lemodule”: “>=1.0.0 <=1.0.7”
}

}

However, version ranges specified in this way were open to possible inconsistencies. For example, while version 1.0.2 is installed on your machine, version 1.0.4 might be installed on your friend’s machine. A possible bug that could be found in 1.0.2 could affect the whole setup. Imagine this appearing in a live environment!

Yarn, on the other hand, started using a special file called yarn.lock with a completely different perspective. If yarn.lock is not present in your project, it is created and updated by Yarn. Inside yarn.lock, information such as the exact version, where the package was downloaded from, and checksum info to check data integrity are kept. In this way, same project users are ensured to work with the same module tree at time t. Since packages are also checked via checksum info, you don’t have to worry.

This innovation was very attractive and was not something developers needed to worry about. However, starting from NPM v5.0.0, NPM automatically started creating its own lock file that does the same thing. The name of this file became package-lock.json.

This structure previously developed by Yarn lost its characteristic of being a huge game-changing advantage once npm also turned to the same working logic.

Output Details

By default, npm is very verbose. For example, when npm install <package> is run, it lists all installed packages recursively. On the other hand, Yarn is not verbose at all. Details can be fetched via other commands, but by default, it lists much less summary, needed information with appropriate emojis (if you are not on Windows).

Security

One of the main reasons Facebook developed Yarn was to better handle npm’s security issues. In npm, packages are allowed to run code automatically and instantly during the installation phase, even automatically and instantly from their dependencies. While this feature has its conveniences, it raises a few security concerns, especially considering the vulnerabilities that can form during the production package building process I mentioned earlier. Conversely, Yarn only installs from your yarn.lock or package.json files. More specifically, yarn.lock ensures that the exact same package is installed on all devices, thus greatly reducing the chance of bugs forming from different versions being installed.

Since these concerns are still in effect at the time of writing, I think Yarn is preferable in terms of security.

Community Data

Conclusion

Even though it is not a fork taken from npm, Yarn covered npm’s shortcomings in many points. Developed along with the needs and pains of companies that shape technology, Yarn continues to be more preferred and used by the community even after npm’s version 5.0. The only problem here is that Yarn’s roadmap is not clear. Pnpm, on the other hand, makes a difference for developers who actively develop too many projects and have the same libraries in many different projects on their computers. But still, in the trials I made on the React Native project we developed ourselves, Yarn, which offers approximately a 25% performance contribution every time, becomes my choice both with its pioneering structure that solves existing problems and with the efficiency it adds in terms of performance.

So, which one is your choice?

Sources:

https://www.kochan.io/nodejs/why-should-we-use-pnpm.html
https://medium.com/pnpm/never-ever-forget-to-install-a-dependency-1c39dd3bbb37
https://github.com/pnpm/benchmarks-of-javascript-package-managers
https://smddzcy.com/posts/2019-05-19/npm-vs-yarn-vs-pnpm-package-manager-comparison
https://flaviocopes.com/pnpm/
https://pnpm.js.org/en/about-package-store
https://iamturns.com/yarn-vs-npm-2018/
https://waverleysoftware.com/blog/yarn-vs-npm/
https://www.keycdn.com/blog/npm-vs-yarn
https://github.com/appleboy/npm-vs-yarn
https://dev.to/urfan/npm-vs-yarn-2a2e
https://ceaksan.com/tr/npm-node-package-manager/

Author: Efecan Tekin

Tags

Development NPM Package Management Pnpm Yarn