Manage Packages or Dependencies NodeJS Project with NPM vs Yarn or PNPM?
When developing applications, there is a need to utilize external packages to ensure the app functions properly.
In software development, these external modules are called dependencies.Managing dependencies involves ensuring all these modules are properly updated, resolving conflicts like versions and ensuring the project has the necessary tools.
In NodeJS, dependencies can be managed using Node Package manager (Npm), Yarn and Pnpm. Although these three are used in NodeJS projects to manage dependencies and ensure the project can access needed packages and run smoothly, they have similarities and differences.
Npm
Npm is a package manager for NodeJS, a JavaScript runtime environment that allows developers to run JavaScript code outside a web browser. It is included with NodeJS and is used to manage code packages that can be easily installed and used in NodeJS projects.
It allows developers to install, update, and manage packages from a centralized repository of publicly available packages. It also enables developers to create and publish packages to the repository for other developers to use.
Yarn
Yarn is a package manager for Node.js and other programming languages. It was developed by Facebook as an alternative to Npm (Node Package Manager) and is now widely used in the NodeJS community. It offers some advantages over Npm, including faster package installation times, improved reliability, and better support for offline development. Yarn achieves faster installation times by using parallel package downloads and caching downloaded packages. This means that subsequent installations of the same package will be faster because the package is already cached locally. Yarn also offers improved reliability through its lockfile mechanism, which ensures that all developers working on a project are using the same version of packages. This helps to prevent issues where different developers are using different package versions, which can cause conflicts and bugs in the code.
Pnpm
Pnpm is fast. How fast? In most cases, it’s quicker than npm and yarn. It can even get to three times faster than npm on a fresh install!
But not only that. pnpm will save you LOTS of gigabytes on your computer.
The magic behind pnpm is with how it handles your packages.
Let's say you have installed the famous NodeJS framework Express using pnpm.
/**
* If you're using NodeJS version 16.13 or higher, you get pnpm out-of-the-box.
* All you have to do is enable it using "corepack enable" command.
*/
npm i -g pnpm
pnpm init && pnpm i express
Express has a bunch of dependencies itself, as you can examine in its package.json (array-flatten, body-parser, and many more).
Where do we store the dependencies of Express (sub-dependencies)?
npm will have to create another node_modules folder in the express folder, but this is not the case with pnpm.
Actually, this is not the case with npm either. Historically (from npm version 2 and below), npm was using nested node_modules, but due to a limitation on windows (windows allows only up to 256 chars for directories paths) and some more reasons, they changed to the way it works.
They now use an algorithm to hoist all sub-dependencies to the root directory of the node_modules.
领英推荐
But this method has a disadvantage:
There could be a situation where I use one of the sub dependencies in my project, but I didn’t install them.
// For example
const parser = require('body-parser');
I didn't install this package (it's not in my package.json dependencies, only in Express package.json), but I can use it since npm hoisted it to my root node_modules.
There's no problem as long as the maintainers of Express decide that body-parser stays part of its dependencies.
However, if they decide to remove it on a later version, this will break my project (I'm trying to import from a package that does not exist).
pnpm approach is more intelligent. It stores all the packages in a folder called .pnpm in your node_modules folder. It will then use a symbolic link (symlink) to point to that folder.
This way, we avoid deeply nested folders while preventing the possibility of importing packages that we didn't install in our project.
Lastly and most importantly, as we mentioned, pnpm will save you tons of storage in your computer.
How? pretty simple. Let's continue with the Express example. When installing Express in our project, pnpm will first save all of its files in a global store (using hashes). This way, the next time we install Express (in another project), pnpm will hard link to the files that exist in the global store.
Feature Comparison
pnpm fetch: Fetch packages from a lockfile into virtual store, package manifest is ignored. This command is specifically designed to improve building a docker image.
pnpm dedupe: Perform an install removing older dependencies in the lockfile if a newer version can be used.
pnpm env <cmd>: Manages the Node.js environment.
And many more new features to improved the way to manage node_modules in NodeJS project and can check more details