Skip to content

pnpm - a fast disk space efficient package manager#

I came across into a scenario where I have multiple Node.js projects or directories and turns out that it has its own copies of node_modules for each folder which accumulates large sizes on disk.

Learning about pnpm package manager made me realize that it is fast as it reuses packages already installed instead of creating another copy of the package which adds space in disk.

Motivation#

Tip

You can also go visit: https://pnpm.io/motivation

https://www.youtube.com/embed/ZIKDJBrk56k?si=qtW8DBxNg-c0rA1Y

Installation#

Reference: https://pnpm.io/installation#using-npm

cli
npm install -g pnpm@latest-10

Usages#

Installing node packages#

cli
pnpm install # install ALL dependencies and dev-dependencies from package.json
# ==> Creates `pnpm-lock.yaml`

pnpm add <pkg-name>
pnpm add -D <pkg-name> # single dev-dependency
cli
npm install # install ALL dependencies and dev-dependencies from package.json
# ==> Creates `package-lock.json`

npm install <pkg-name>
npm install -D <pkg-name> # single dev-dependency

Running scripts#

cli
pnpm start # start script from package.json
pnpm dev # dev script from package.json
cli
npm start # start script from package.json
npm run dev # dev script from package.json

Migration#

Existing package-lock.json#

Moving to pnpm but already have existing package-lock.json?

cli
pnpm import

Generates a pnpm-lock.yaml based on package-lock.json

Existing pnpm-lock.yaml#

Moving back to npm?

When you don't have the package-lock.json but has pnpm-lock.yaml

cli
npm install --package-lock-only

Generates a package-lock.json and would NOT actually install or touch node_modules

Known Issues#

Importing a dependency of your dependency#

  1. For example you have installed a node package which is a direct dependencies or devDependencies in your package.json.

  2. And it depends on another package called uuid for an instance.

  3. And you directly import uuid as part of your application.

Then using npm, you may not encounter an error.

But using pnpm may throw an error.

In this case, you must hoist uuid in the root level of your node_modules

.npmrc
shamefully-hoist=true

Reinstall node_modules via pnpm install after configuring .npmrc

Reference: https://pnpm.io/settings#shamefullyhoist

Info

This happens because npm commonly installs ALL dependencies and its dependencies in your root node_modules. Meanwhile, this may not be the same for pnpm.

Module Not Found#

After initial pnpm install, you may encounter this warning.

cli
 Warning ───────────────────────────────────────────────────────────────────────────────────╮
│                                                                                            │
│   Ignored build scripts: @apollo/protobufjs, @nestjs/core, node-snowball.                  │
│   Run "pnpm approve-builds" to pick which dependencies should be allowed to run scripts.   │
│                                                                                            │
╰────────────────────────────────────────────────────────────────────────────────────────────╯

You may ignore it.

But you may encounter issues after npm start / npm run dev / pnpm start / pnpm dev:

Error: Cannot find module './build/Release/snowball'`

The reason is, under the hood, your dependency is importing a module from a "build" that was not generated.

npm command will always allow build, especially few dependencies have a postinstall which triggers the build to be generated.

However, pnpm will not allow this by default. Therefore, if your dependencies require these builds.

Then you have to approve those builds.

cli
pnpm approve-builds

After successfuly operation, this command generates a pnpm-workspace.yaml

This will display a list of build scripts which you can select from.

We will select node-snowball as we should know that it has a postinstall script to create or generate the './build/Release/snowball'.

pnpm-workspace.yaml
ignoredBuiltDependencies:
  - '@apollo/protobufjs'
  - '@nestjs/core'

onlyBuiltDependencies:
  - node-snowball

Comments