PettyUI/.firecrawl/pkgpulse-packagemgr.md
Mats Bosson db906fd85a Fix linting config and package fields
- Replace .eslintrc.cjs with eslint.config.mjs (ESLint 9 flat config)
  using direct eslint-plugin-solid + @typescript-eslint/parser approach
- Add @typescript-eslint/parser to root devDependencies
- Add main/module/types top-level fields to packages/core/package.json
- Add resolve.conditions to packages/core/vite.config.ts
- Create packages/core/tsconfig.test.json for test type-checking
- Remove empty paths:{} from packages/core/tsconfig.json
2026-03-29 02:35:57 +07:00

8.6 KiB

Skip to main content

TL;DR

pnpm is the 2026 default for serious JavaScript projects — content-addressable store, strict dependency isolation, and the best monorepo support. Bun is 5-10x faster than pnpm on installs but still has edge cases with niche packages. npm is the default that works everywhere but is the slowest. For new projects: pnpm (or Bun if you're already in the Bun ecosystem). For CI speed: Bun's install is often faster than even pnpm's cached install.

Key Takeaways

  • Bun install: 5-10x faster than pnpm, 15-25x faster than npm (measured on real projects)
  • pnpm: Strictest isolation (prevents phantom dependencies), best workspace support, most compatible
  • npm: Default, slowest, but universally compatible, node_modules phantom deps allowed
  • Disk usage: pnpm uses ~50% less disk space vs npm (content-addressable store deduplication)
  • Monorepos: pnpm workspaces > Bun workspaces > npm workspaces (feature parity gap)
  • 2026 recommendation: pnpm for serious projects; Bun install if on Bun runtime already

Downloads / Usage

Package Manager Weekly Downloads Trend
npm Default (Node.js) → Stable
pnpm ~7M downloads/week ↑ Growing
bun ~1.5M downloads/week ↑ Fast growing

Install Speed Benchmarks

Benchmark: Next.js 15 project (1,847 packages)
Environment: M3 MacBook Pro, SSD, cold/warm cache

COLD INSTALL (no cache, no lockfile):
  npm:   82s
  pnpm:  31s  (2.6x faster than npm)
  Bun:    8s  (10x faster than npm)

CACHED INSTALL (lockfile present, store exists):
  npm:   45s  (reads node_modules hash)
  pnpm:   4s  (hardlinks from content store)
  Bun:  0.8s  (binary cache, near-instant)

CI INSTALL (lockfile present, fresh machine):
  npm:   62s
  pnpm:  18s  (3.4x faster)
  Bun:    6s  (10x faster)

# Install pnpm:
npm install -g pnpm
# Or via Corepack (Node.js built-in):
corepack enable pnpm

# Common commands:
pnpm install                     # Install from lockfile
pnpm add react                   # Add dependency
pnpm add -D typescript           # Add dev dependency
pnpm remove lodash               # Remove package
pnpm update --interactive        # Interactive update UI
pnpm why lodash                  # Why is this installed?
pnpm ls                          # List installed packages
# .npmrc — pnpm configuration:
# Enforce strict peer dependencies:
strict-peer-dependencies=true

# Hoist patterns (allow certain phantom deps for compat):
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*

# Save exact versions:
save-exact=true

# Node linker (for compatibility with some tools):
# node-linker=hoisted  # Falls back to npm-style if needed
// pnpm-workspace.yaml — monorepo config:
{
  "packages": [\
    "apps/*",\
    "packages/*",\
    "tools/*"\
  ]
}
# pnpm workspace commands:
pnpm --filter web add react-query         # Add to specific package
pnpm --filter "!web" install              # Install all except web
pnpm -r run build                         # Run build in all packages
pnpm --filter web... run build            # Build web + its dependencies
pnpm --filter ...web run build            # Build packages that depend on web

Why pnpm Over npm

pnpm advantages:
  → No phantom dependencies (package.json must declare everything)
  → 50% less disk usage (hardlinks, not copies)
  → 3-5x faster installs than npm
  → Best workspace support (filtering, recursive)
  → Isolated node_modules (each package sees only its deps)

pnpm limitations:
  → Occasional compatibility issues with poorly-written packages
  → Slightly steeper learning curve for teams migrating from npm
  → Some tools (older ones) expect hoisted node_modules

Bun: When Speed Is Everything

# Install Bun:
curl -fsSL https://bun.sh/install | bash

# Bun install commands (compatible with npm syntax):
bun install                      # Install from lockfile
bun add react                    # Add dependency
bun add -d typescript            # Add dev dependency (note: -d not -D)
bun remove lodash                # Remove
bun update                       # Update all packages
# bun.lock — Bun's lockfile format:
# Binary lockfile (bun.lockb) in older versions
# Text lockfile (bun.lock) in Bun 1.1+
# Commit bun.lock to version control
# bunfig.toml — Bun configuration:
[install]
# Use a private registry:
registry = "https://registry.npmjs.org"
exact = true  # Pin exact versions

[install.scopes]
# Scoped registry:
"@mycompany" = { token = "$NPM_TOKEN", url = "https://npm.mycompany.com" }
# Bun workspaces:
# package.json at root:
# {
#   "workspaces": ["apps/*", "packages/*"]
# }

bun install                      # Installs all workspaces
bun add react --workspace apps/web  # Add to specific workspace
bun run --filter '*' build       # Run build in all workspaces

Bun Install Limitations

Known compatibility issues in 2026:
  → Some native binaries may not install correctly
  → Postinstall scripts: some packages assume npm/node environment
  → pnpm-specific workspace.yaml not supported (use package.json workspaces)
  → Some packages with complex resolution logic may resolve differently

Test your project before switching to Bun install in CI:
  bun install && bun test  # Quick compatibility check

npm: Universal Compatibility

# npm — the universal fallback:
npm install                      # Install
npm install react                # Add
npm install -D typescript        # Add dev
npm uninstall lodash             # Remove
npm update                       # Update

# npm workspaces (basic):
# package.json: { "workspaces": ["apps/*", "packages/*"] }
npm install                      # Installs all workspaces
npm run build --workspace=apps/web  # Run in specific workspace
npm run build --workspaces          # Run in all workspaces

Corepack: Managing Package Managers

// package.json — specify exact package manager:
{
  "packageManager": "pnpm@9.15.0"
}
# Enable Corepack (Node.js 16+):
corepack enable

# Now the packageManager field is enforced:
# If you run npm install in a pnpm project, Corepack intercepts:
# "This project requires pnpm@9.15.0. Run 'corepack use pnpm@9.15.0' to switch."

# In CI — enable Corepack before install:
corepack enable
# Then just run: pnpm install (or whatever packageManager specifies)

Decision Guide

Use pnpm if:
  → New project, want best practices
  → Monorepo with multiple packages
  → Strict dependency isolation important
  → Most compatible choice that's still fast

Use Bun (install) if:
  → Already using Bun as runtime
  → CI speed is critical and you've tested compatibility
  → Greenfield project with modern packages only

Use npm if:
  → Maximum compatibility needed (legacy projects)
  → Required by tooling that expects npm conventions
  → Team unfamiliar with pnpm/Bun
  → Deploying to environment where only npm is available

Compare package manager downloads on PkgPulse.

Comments

The 2026 JavaScript Stack Cheatsheet

One PDF: the best package for every category (ORMs, bundlers, auth, testing, state management). Used by 500+ devs. Free, updated monthly.

Get the Free Cheatsheet