Skip to content

Upgrade package manager #191

@mtmacdonald

Description

@mtmacdonald

We need to upgrade from ancient yarn v1. Here's a quick write-up of some reading around on the options. This is obviously a bit subjective, but gives some "feel" over what to choose.

Package manager popularity / trends comparison

  • Weekly downloads (from NPM registry)
    • pnpm: 43 million
    • yarn v1 classic 6 million, "modern (berry)" 580k @yarnpkg/core
  • Github stars
    • pnpm: 33.7k
    • yarn: v1 classic 41.5k, "modern (berry)" 8k
  • Stackoverflow survey 2025
    • yarn still more popular
    • pnpm more admired and desired
  • StateofJS Survey 2024
    • pnpm more popular, trending up

Key differentiators

  • npm:
    • ↑ Core Node tool, ubiquitous
    • ↓ Slow, flatter innefficient node_modules (less disk efficient), slow filesystem-based dependency searching, difficult to verify valid installation, duplication of installs, modules have access to packages they do not depend on (implicit dependencies)
  • yarn:
    • ↑ Fast (with PnP) - uses .yarn/cache (metadata, zip archives) + .pnp.cjs (package references) instead of nodes_modules, efficient de-duplication, more deterministic across environments, stricter access rules, better install verification, strong workspaces, verification through checksums
    • • Facebook-backed, Plug-n-Play archictecture (no node_modules by default), slightly more disk efficient (hoisting)
    • ↓ Steep learning curve (berry), known compatibility issues with legacy packages
  • pnpm
    • ↑ Drop-in replacement for npm, fastest, disk-efficient (no duplication via global store with symlinks / hardlinks), strict dependency rules (prevents access to non-declared packages). We still have a node_modules, but it has symlinks. The node_modules/.pnpm contains hardlinks to the actual global store, verification through checksums
    • • Zoltan Kochan (bit.dev)
    • ↓ None identified yet
  • Deno, JSR registry
    • deno is a JavaScript runtime by Ryan Dahl, original Node Dev, written in rust. Ships with its own built-in package manager (deno add etc)
    • Has a separate registry called jsr, not a Node-compatible CLI tool. See jsr.io - example es-toolkit
    • There is a compatibility layer and you can do for example pnpm install jsr:@es-toolkit/es-toolkit in a non-deno project, that uses the main NPM registry for some packages.
    • ↑ Registry: ESM-only and TypeScript-first, built-in package scoring (quality), security-focussed
    • ↓ Not all mainstream packages are in this registry
  • Bun
    • bun is a JavaScript runtime by Jarred Sumner, aquired by Anthropic / Claude AI, written in Zig. Ships with own package manager.
    • bun package manager is a Node.js-compatible
    • ↑ Speed-focussed, claims to be faster than pnpm and closer to Node-compatibility than Deno
    • ↓ Weaker workspace support? Stability?

Workspace support: all the tools support workspaces, but there maybe strengths/weaknesses.

Gut feel: leaning towards pnpm, open to modern yarn. The Deno and Bun ecosystems are interesting, but for now we want to stay "mainstream" (can be a separate future discussion).

Command mappings

Feature Yarn (classic v1) pnpm
Install dependencies yarn pnpm install
Add package yarn add <pkg> pnpm add <pkg>
Add dev dependency yarn add -D <pkg> pnpm add -D <pkg>
Remove package yarn remove <pkg> pnpm remove <pkg>
Upgrade package yarn upgrade pnpm upgrade
Interactive upgrade yarn upgrade-interactive pnpm upgrade -i
Run arbitrary package npx pnpx
Run script yarn <script> pnpm <script>
Run binary yarn <bin> pnpm <bin>
Clean cache yarn cache clean pnpm store prune
List dependencies yarn list pnpm list

Further reading

One link had a helpful comparison:

Image

Decision

  • pnpm seems a good choice for this project. Implementation is in #196

Metadata

Metadata

Assignees

Labels

choredependenciesPull requests that update a dependency file

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions