In modern application development, we don’t write everything from scratch. Instead, we prefer to use existing open-source packages. Each of these packages has its own maintainers and community. So, using a package in our projects gives us some advantages like faster development, access to new, regular updates, and better security than custom-created script.
It’s common that one package depends on many other packages to work correctly. Similarly, the other packages may also depend on something like lodash, but lodash itself depends on several packages as well. In other words, the nested dependencies can sometimes become so complex that they are unable to handle dependency management manually.
Here’s when a package manager is extremely useful. Package managers are tools that automatically handle the dependencies of a project.
Overview of package managers
npm was the first package manager to introduce the concepts of registry protocol and packaging standards. It was released back in 2010 and officially adopted by the Node.js team shortly afterward, which was the turning point for npm.
But there are few drawbacks of npm that triggered the development of Yarn and pnpm. For example, npm is significantly slower than its counterparts. It also has a history of serious security vulnerabilities.
So, big tech companies like Facebook and Google were hesitant to keep using npm. In turn, they joined efforts to develop a better version of npm and call it Yarn. Meanwhile, Ukrainian developer Zoltan Kochan developed pnpm.
Features of npm, Yarn, and pnpm
All of these package managers are open-source, meaning you have full access to check the inner workings of each one. Sometimes this is even a requirement in enterprise-level application development.
Benefits of npm:
- Automatically generates a
package-lock.jsonfile. It’s useful to commit to a version control system. This way, other developers can easily install the dependencies on their local machines
- Manage local or global dependencies with ease
- npm is well equipped to handle multiple versions of dependencies
- It has an official registry that has more packages than pypi, rubygems, or packagist
Benefits of Yarn:
- Yarn fixes many issues that appear in a Monorepo. For example, if you are maintaining multiple packages under the same repository and they all have a separate
package.jsonfile, you can update all packages easily with Yarn, thanks to its concept of workspaces that can install dependencies of all packages in a repository, all in one go. With npm, you’d need to run the
npm installcommand manually within each package folder.
- Yarn makes use of an offline cache mechanism, meaning that when you install a package for the first time, Yarn adds it to a cache folder under
~/.yarn-cache. So, the next time you need this package, Yarn will retrieve it from the local cache instead of making an HTTP request to the server. This small enhancement significantly boosts the performance of Yarn compared to npm
- Yarn also makes use of a lock file called
yarn.lock, so your projects will work correctly for all teammates. This concept is also referred to as a deterministic install algorithm
- It’s packed with a built-in license checker that can be handy in different scenarios when you’re developing applications
- Unlike npm, Yarn uses an approach called parallel downloads. It enables Yarn to utilize more resources to speed up the build process
- It can automatically retry the HTTP request in case of failure. This feature is particularly useful when you are facing temporary internet issues
Benefits of pnpm:
- It’s compatible with npm but also offers significantly better disk space usage and speed
- pnpm installs all packages on a single location and then uses symlinks to reference them. It introduces a completely new concept called a content-addressable storage system that enables pnpm to detect the difference between files. In turn, it doesn’t duplicate unchanged files in two different versions of a package
- Its latest version, 5.8.0, introduces a new Yarn-bash-like setting called shell-emulator, a cross-platform shell environment
- pnpm has a strict access control mechanism, meaning that a package can only access the dependencies that are defined in its
Package manager comparison
Ease of use
npm, Yarn, and pnpm offer almost identical commands for their various operations, and they are all easy to use. Here’s an example of their commonly used commands:
|npm install||yarn install||pnpm install|
|npm update||yarn upgrade||pnpm update|
There’s no match to pnpm when it comes to the speed and performance of these package managers. According to a benchmark of different use cases, pnpm has shown performance speeds up to 3x faster than npm.
The speeds of Yarn and npm are comparable. In some cases, Yarn has a significant advantage over npm, but there are scenarios where npm is a more suitable choice. For example, if we perform an install operation by just using
node_modules and skip
lock file functionality, then npm could offer 5x better speed. Similarly, if we use all three functionalities, then Yarn could boost its performance and becomes 11x faster than npm.
The major advantage of Yarn over npm is that it verifies the integrity of each package using checksums. The verification process is done before executing any code from the package, so it discards any chances of package hijacking vulnerability.
On the other hand, npm is a bit more forgiving when it comes to working with bad packages. It is still evolving in order to offer the best practices for security. But, npm generally has a bad reputation in terms of security.
In the past, there were some security vulnerabilities in npm that directly affected many projects. For example, in npm version 5.7.0, when you execute
sudo npm command on a Linux-based operating system (OS), there was a possibility to change the ownership of system files, rendering the OS unusable.
Similarly, another incident of stealing bitcoins happened in 2018. Basically, the popular Node.js package EventStream added a malicious dependency
flatmap-stream in its version 3.3.6. This malicious package was packed with an encrypted payload that tries to steal bitcoins from the developer’s machine.
pnpm combines the positive attributes of both npm and Yarn to provide even better security. It also implements a strict access control mechanism that binds a package to only use its own dependencies that are defined in its
npm, Yarn, and pnpm have gone through several phases over the past few years. Over time, their codebase has matured because they’ve received tons of contributions from the open-source community.
And, with the passage of time, new concepts and ideas appear that could introduce breaking changes. At the time of writing this guide, all these package managers are in good shape and you can use them in your projects without any issues.
Yarn is backed by Facebook and Google, npm is backed by Microsoft and Node.js, and pnpm is mostly developed by an individual, although it now has 75+ contributors — so you can depend on these package managers to create your next project.
Support for monorepos
Monorepos are mostly preferred by large tech companies to store and manage their massive codebases. npm was only designed to manage individual projects. As of now, it doesn’t have any functionality to support monorepos. But both Yarn and pnpm have complete support for monorepos, thanks to their concept of workspaces.
Deterministic — the lock file
All three package managers are packed with the functionality of the lock file. It allows different developers to install the exact same copy of the project. npm uses a
package-lock.json file, Yarn uses
yarn.lock, and pnpm uses
If you are searching for a solution that gives you better speed and efficient memory usage, you should strongly consider using pnpm.
If you are handling monorepos, you can use pnpm or Yarn to do so. However, keep in mind that Yarn sends usage data to Facebook, which may not make Yarn a suitable choice in some scenarios.
Yarn also doesn’t support version 5 of Node.js. In this regard, npm is a preferred option for Node.js-based projects because it is recommended by the Node.js team. These days, Node.js comes with npm by default.
With npm, you should consider its history with security issues, which triggered the development of Yarn, which was also created to solve many issuers that were present in npm. So, if you’re concerned with security of your projects, consider using Yarn instead of npm.
Debugging code is always a tedious task. But the more you understand your errors the easier it is to fix them.