Skip to content

Use pnpm instead of npm for package management#1107

Open
RagingCactus wants to merge 3 commits intographefruit:developfrom
RagingCactus:pnpm
Open

Use pnpm instead of npm for package management#1107
RagingCactus wants to merge 3 commits intographefruit:developfrom
RagingCactus:pnpm

Conversation

@RagingCactus
Copy link
Copy Markdown
Collaborator

@RagingCactus RagingCactus commented Mar 31, 2026

Rationale

npm development is behind most of the JS package manager ecosystem. npmonly very recently started introducing a setting to ignore packageversions younger than a specified time frame to help defend againstsupply chain attacks. Furthermore, npm still runs postInstall scripts by default on any package, increasing the risk further.

On top of that, we recently had a bunch of problems with npm generating bad lock files, see npm/cli#8669.

And last but not least, npm is rather slow and likes to waste disk space on every opportunity. Its lock files are also terrible to diff.

pnpm should be an improvement on all of these fronts. It does NOT execute build scripts by default, it has a very easy way to specify a minimum age for new package versions, and its lock files look much better to a human in a diff.

Security

With this PR, the following configuration is being set in pnpm-workspace.yaml:

# Delay new version of libraries for 10080 minutes (7 days) in an attempt to
# defend against increasingly common supply chain attacks on npm packages.
# See https://pnpm.io/settings#minimumreleaseage and
# https://pnpm.io/supply-chain-security
minimum-release-age: 10080

This means that pnpm will only consider versions for dependency resolution that are at least 7 days old. This should improve our resilience against supply chain attacks like the recent attack on axios (see https://www.stepsecurity.io/blog/axios-compromised-on-npm-malicious-versions-drop-remote-access-trojan and axios/axios#10604) because hopefully someone discovers the malicious version in these 7 days.

Furthermore, pnpm by default disallows build scripts in dependencies. Packages that require build scripts must be explicitly whitelisted in pnpm-workspace.yaml as shown here:

# Allow the build scripts for the angular build dependencies listed here.
# Do NOT blindly add new dependencies here when an error pops up. Build scripts
# are a common supply chain attack vector for malware!
allowBuilds:
  '@parcel/watcher': true
  esbuild: true
  lmdb: true
  msgpackr-extract: true
  sharp: false # As recommended by https://github.com/lovell/sharp/blob/7b4c4762432b14c62676e860c8034b5cd326f464/docs/src/content/docs/install.md?plain=1#L23

Notice to developers

Warning: When testing this or after this is merged, developers will need to rm -r node_modules once!
After that, just pnpm install and everything should work. Just remember to always use pnpm instead of npm and pnpx instead of npx in Beanconqueror.

Testing

This needs a quick test to see if the ios build still works. Android works fine, I tested that.

Discussion

Feel free to discuss this, this is just a proposal. It just stems from the fact that personally I've had it with npm now. The weird lock file issues in CI and with PRs, the default of just running any postInstall script by default, and now the bad configurability regarding supply chain hardening. I'm not a pnpm fanboy or anything, it just looked like a well-known, widely used, and more sane alternative.

pnpm is strict about us having to declare all dependencies we use
directly, even if they are brought in transitively through other
dependencies.

All of these dependencies were already in the project, but were
erroneously not being declared as being direct dependencies. This is
required to make the application build correctly when using pnpm.
npm development is behind most of the JS package manager ecosystem. npm
only very recently started introducing a setting to ignore package
versions younger than a specified time frame to help defend against
supply chain attacks. Furthermore, npm still runs postInstall scripts by
default on any package, increasing the risk further.

On top of that, we recently had a bunch of problems with npm generating
bad lock files, see npm/cli#8669.

And last but not least, npm is rather slow and likes to waste disk space
on every opportunity. Its lock files are also terrible to diff.

pnpm should be an improvement on all of these fronts. It does NOT
execute build scripts by default, it has a very easy way to specify a
minimum age for new package versions, and its lock files look much
better to a human in a diff.

This commit removes the old npm package-lock.json, adds the pnpm lock
file instead and also adds pnpm settings. It also updates all
documentation, comments, and CI scripts to use pnpm.
This prevents confusion when trying to use old versions of node or pnpm.

This configuration will also cause accidental invocations of npm to
error, which is great to ease the transition to pnpm.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant