- DevsWorld
- Posts
- Exploring pnpm
Exploring pnpm
A Faster Package Manager for JavaScript
Welcome back to another newsletter!
I recently install pnpm into my projects after watching a YouTube video on how it works. It’s flippin’ fast!
For a while now, npm has been my go-to package managers for JavaScript projects. I’ve used yarn professionally, but it’s dying from what I can tell. NPM is popular as it’s essentially the “default” package manager for node. It does what it needs to be, but to be honest, it’s slow and frustrating.
In comes pnpm!
With pnpm, you get faster installations, efficient disk usage (all projects use a central package manager cache!), and more happiness.
How does it work?
pnpm uses a pnpm-workspace.yaml
file instead of a package-lock.json
file to lock file dependencies. This file defines your project workspaces, their dependencies, and interdependencies. What's brilliant is that the YAML file is not just a configuration; it also stores hashes of dependencies and their versions, creating a consistent environment across your projects. When you run pnpm, it ensures that your project's dependencies match the defined versions in the YAML file. The hash creates a hard link between a global storage and the node_modules
folder in the workspace. Using a hard link allows the files to look like they are new files, but in fact, they are using the same disk space as the global storage.
Why Use It?
There’s a places I could see pnpm being quite useful.
Local Development
pnpm is quite fast for development. Adding new packages is extremely fast and efficient. Where pnpm shines the most though is when you have multiple projects on your computer. Since the dependencies are hard-linked, if the dependency already exists in local storage, there’s no need to re-download it into a new node_modules
directory. I personally have 10-15 different TypeScript/JavaScript projects on my laptop. Each node_modules
directory takes up a chunk of space. By using pnpm, you’re effectively reducing the amount of disk space for all projects on the system.
CI
In CI, I could see pnpm being quite useful, especially for microservices applications. If you have multiple microservices that need to be built, it would be wise to build via pnpm and maintain the dependency cache. You will see a significant improvement in build speed, I can guarantee it!
Switching from npm to pnpm
How do you make the switch then?
To be honest…
It was extremely easy.
Here’s some commands to do this:
Starting at the root of the project you want to switch, do the following:
# This will remove node_modules
$ npx npkill
# Add the following line to your package.json file
"scripts": {
"preinstall": "npx only-allow pnpm",
...
}
# Create a new file called pnpm-workspace.yaml
touch pnpm-workspace.yaml
# Add the following content into the file:
packages:
# include packages in subfolders (e.g. src/)
- "src/**"
# if required, exclude some directories
- '!**/test/**'
# This will create a lock file (pnpm-lock.yaml) from your current package.json dependencies
$ pnpm import
# You can now remove your package-lock.json or yarn.lock file
$ rm yarn.lock
$ rm package-lock.json
# Run pnpm install to install packages
$ pnpm i
# Last thing to do is, in your package.json, replace any usage of npm <command> with pnpm <command>. For example:
"start": "npm start" -> "start": "pnpm start"
This took me ~5 minutes to do give or take, which is quite fast for switching package managers in my opinion!
If you decided to use pnpm in a project, let me know on Twitter! I’d love to hear about your experience with the tool.
If you enjoyed this content, please share it with someone who you feel would also like to read more about DevOps and software engineering alike! Next week, I plan to dive deep into turborepo. It’s a new tool that I’ve started using that helps improve the speed and efficiency of building a monolithic repo.