Client Area

JavaScript/Node Package Managers The Complete, HandsOn Guide (npm Yarn pnpm Bun)

7 min readPublished 4 Mar 2026Updated 14 Apr 2026870 views

In this article

  • 11) What does a package manager do
  • 22) Options at a glance
  • 33) Core concepts (that apply to all)
  • 44) npm -- the reliable default
  • 55) Yarn -- Classic vs Berry

TL;DR Summary

  • npm best default: simple, builtin, reliable workspaces.

  • pnpm fastest + most spaceefficient for big monorepos; strict linking.

  • Yarn Berry PnP (no node_modules) + zeroinstall; powerful but opinionated.

  • Yarn v1 legacy, fine to maintain, but new features are in Berry.

  • Bun very fast, integrated runtime/tester; ecosystem still maturing.

Commit one lockfile. Pin Node & tool versions. Use workspaces. Enforce overrides/resolutions. Use ci/immutable installs in CI.


1) What does a package manager do

  • Resolves dependency versions from package.json (incl. transitive deps).

  • Writes a lockfile for reproducible installs.

  • Installs packages into node_modules (or a virtual FS in Yarn PnP).

  • Exposes project CLIs via node_modules/.bin/.

  • Supports workspaces/monorepos.

  • Talks to an npm registry (public/private) with auth, caching, proxies.


2) Options at a glance

Manager Lockfile Install model Workspaces Superpowers Tradeoffs
npm package-lock.json Classic node_modules Yes (v7+) Ubiquitous, easy, 1stparty, good defaults Not the absolute fastest; fewer monorepo niceties than pnpm
Yarn v1 (Classic) yarn.lock Classic node_modules Yes Battletested; common in older monorepos Legacy; new work focuses on Berry
Yarn Berry (v2+) yarn.lock PnP (or nodemodules via plugin) Yes Zeroinstall, constraints, plugins, very fast PnP may break tools that expect node_modules; learning curve
pnpm pnpm-lock.yaml Linked node_modules from contentaddressable store Yes Diskefficient, fast, strict, great filters Some tools assume flat hoisting; needs tweaks
Bun bun.lockb Classic node_modules Basic Blazing fast + runtime/test Binary lockfile; ecosystem still maturing

Managerofmanagers: Corepack (bundled with Node 16.17) pins Yarn/pnpm versions via packageManager in package.json.


3) Core concepts (that apply to all)

  • Lockfile Deterministic graph; must be committed.

  • Hoisting Flatten deps to toplevel; convenient but can mask duplication.

  • Peer deps Required by consumers; misaligned peers cause install errors.

  • Overrides/Resolutions Force versions of nested deps (npm/pnpm: overrides, Yarn: resolutions).

  • Workspaces Single repo, many packages, one lockfile; local linking.

  • Scripts npm run, yarn, pnpm expose CLIs from .bin.

  • Corepack Declares & provisions Yarn/pnpm versions per project.


4) npm -- the reliable default

Why npm

  • Ships with Node, minimal friction, strong CI/Docker ergonomics.

  • Modern npm supports workspaces, peerdep autoinstall, overrides.

Common commands

npm i # install
npm ci # clean, lockfileonly install for CI
npm run -ws build # run script in all workspaces
npm run build -w pkg # run in one workspace
npm outdated && npm audit

Helpful snippets

// package.json (excerpt)
{
 "private": true,
 "workspaces": ["apps/*", "packages/*"],
 "engines": { "node": ">=20 <21" },
 "packageManager": "npm@10"
}
# .npmrc
engine-strict=true
fund=false
audit=true
// npm overrides
{
 "overrides": {
 "ansi-regex": "6.0.1",
 "react-dom@^18": "18.3.1"
 }
}

5) Yarn -- Classic vs Berry

Yarn v1 (Classic)

  • Familiar node_modules layout, workspaces OK.

  • Good for maintaining existing repos without big changes.

Yarn Berry (v2+)

  • PnP: virtual filesystem; optionally switch to node-modules linker.

  • Zeroinstall: commit .yarn/cache to avoid network in CI.

  • Plugins: Constraints, version policies, interactive upgrades.

Berry basics

# .yarnrc.yml
nodeLinker: pnp # or 'node-modules'
yarnPath: .yarn/releases/yarn-4.x.cjs
npmRegistryServer: https://registry.npmjs.org/
// package.json
{ "resolutions": { "left-pad": "1.3.0" } }
yarn install --immutable
# Run in all workspaces
yarn workspaces foreach -A run build

6) pnpm -- fast & spaceefficient

Why pnpm

  • Contentaddressable store + symlinked node_modules saves disk.

  • Strict linking catches phantom deps early.

  • Excellent monorepo filters & commands.

Workspace setup

# pnpm-workspace.yaml
packages:
 - "apps/*"
 - "packages/*"
# .npmrc (pnpm respects many npmrc keys)
shamefully-hoist=false
strict-peer-dependencies=true
pnpm install
pnpm -r build # recursive in all packages
pnpm -F @scope/pkg test # filter target
pnpm prune --prod

7) Bun -- speed + allinone runtime

  • bun install is very fast; lockfile is binary (bun.lockb).

  • Bundled test runner & runtime -- great for prototypes/greenfield.

  • Ensure ecosystem tools (plugins/CLIs) behave as expected.

bun install
bun run build

8) CI/CD recipes (copypaste friendly)

GitHub Actions -- npm

- uses: actions/setup-node@v4
 with: { node-version: '20', cache: 'npm' }
- run: npm ci
- run: npm run -ws build --if-present
- run: npm test --workspaces --if-present

GitHub Actions -- pnpm

- uses: actions/setup-node@v4
 with: { node-version: '20', cache: 'pnpm' }
- run: corepack enable
- run: pnpm install --frozen-lockfile
- run: pnpm -r build

GitHub Actions -- Yarn Berry

- uses: actions/setup-node@v4
 with: { node-version: '20' }
- run: corepack enable
- run: yarn install --immutable
- run: yarn workspaces foreach -A run build

9) Docker patterns (prodready)

Builder Runtime (npm)

FROM node:20 AS deps
WORKDIR /app
COPY package.json package-lock.json ./
COPY packages/*/package.json apps/*/package.json ./
RUN npm ci --include-workspace-root

FROM node:20 AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run -ws build

FROM node:20-slim
WORKDIR /app
COPY --from=build /app .
RUN npm prune --omit=dev
CMD ["node","apps/api/dist/main.js"]

Yarn Berry: copy .yarn + yarn.lock, use yarn install --immutable.
pnpm: install via Corepack and use pnpm-lock.yaml.


10) Migration playbooks

Yarn v1 npm

  1. Replace yarn <script> with npm run <script>.

  2. Convert resolutions npm overrides.

  3. Generate fresh package-lock.json with npm ci.

npm pnpm

  1. Add pnpm-workspace.yaml.

  2. Fix peerdep warnings; avoid assuming flat hoist.

  3. Use pnpm install --frozen-lockfile in CI.

Yarn v1 Yarn Berry

  1. Add .yarnrc.yml + choose pnp or node-modules linker.

  2. (Optional) Enable zeroinstall by committing .yarn/cache.

  3. Patch tools that expect node_modules or switch to nodemodules linker.


11) Troubleshooting cookbook

  • Peer dependency conflict Align at the top level or use overrides/resolutions.

  • Lockfile merge hell Reinstall from clean tree; avoid manual edits; regenerate.

  • EAI_AGAIN / network flakiness Use registry mirrors/caching; Yarn zeroinstall; pnpm store.

  • Native addon fails on new OS/arch Reinstall on target OS; don't copy node_modules across OSes.

  • Tool mismatch Enforce via packageManager + a preinstall guard.

Preinstall guard (enforce npm only)

{
 "scripts": {
 "preinstall": "node -e \"const ua=process.env.npm_config_user_agent||''; if(!ua.startsWith('npm/')){console.error('Use npm only.'); process.exit(1)}\""
 }
}

12) Security & compliance

  • Use scoped tokens in CI; never commit secrets.

  • Enable 2FA on registry accounts.

  • Regularly audit (npm audit, pnpm audit, yarn npm audit).

  • Pin critical transitive deps via overrides/resolutions.

  • Mirror or proxy registry (Verdaccio/Artifactory) for availability & provenance.


13) FAQ (quick hits)

  • Should I commit node_modules No. Commit only the lockfile.

  • One repo, many packages Use workspaces (npm/pnpm/Yarn all support).

  • Which is fastest pnpm/Yarn Berry are typically faster; Bun is very fast too.

  • Which is safest for a broad team npm or pnpm.

  • Can I mix managers Avoid mixing; enforce a single tool per repo.


14) Glossary

  • Lockfile: Snapshot of exact versions for reproducibility.

  • Hoisting: Lifting nested deps to toplevel node_modules.

  • Peer dependency: A dep you must install at the app level for a package to integrate correctly.

  • PnP: PlugandPlay; Yarn's virtual filesystem that replaces node_modules.

  • Corepack: Node helper that provisions Yarn/pnpm per project.


15) Onepage team checklist

  • Choose: npm / pnpm / Yarn Berry (document why).

  • Pin Node & tool via engines + packageManager.

  • Commit one lockfile at repo root.

  • Use workspaces with a single graph.

  • CI uses ci/immutable/--frozen-lockfile installs.

  • Use overrides/resolutions (never patch inside node_modules).

  • Regular audits; track advisories.

  • Production images prune dev deps.

  • Document commands for devs & CI.


Final take

For most teams: start with npm for simplicity, or pnpm for efficiency at scale. If you want PnP/zeroinstall and can accommodate it, Yarn Berry is excellent. Whatever you choose, lock it down (versions + lockfile), automate CI, and keep the graph healthy with audits and overrides.

Note: Node.js 14 and 16 have reached end-of-life. We recommend using Node.js 20 LTS or Node.js 22 LTS for new projects. Use NVM to install the latest LTS version.

Was this article helpful?

Your feedback helps us improve our documentation

Still need help? Submit a support ticket