C.W.K.
Stream
Lesson 01 of 05 · published

Why npm Is Still the Default

~10 min · npm, overview, javascript

Level 0Newbie
0 XP0/55 lessons0/16 achievements
0/80 XP to next level80 XP to go0% complete

npm — Node Package Manager — has been the default JavaScript package manager since Node.js shipped in 2009. It's older, less clever, and slower than every alternative in this quest. It's also the one you can guarantee every contributor's machine already has, the one every CI image already supports, and the one every JavaScript tutorial assumes. That universal floor is npm's superpower, and it's why it remains the default.

npm v11 (shipped alongside Node.js 24) requires Node.js ^20.17.0 || >=22.9.0. The recent improvements that matter day-to-day: faster installs via better caching, --ignore-scripts applies to all lifecycle scripts (a security hardening), and npm init now prompts for ESM vs CommonJS instead of defaulting silently.

npm has real limitations. The flat node_modules structure allows phantom dependencies — code that imports a package not declared in package.json but happens to be present because something else needed it. Installs are slower than pnpm or Bun (~57s vs ~9s for a Next.js install). The lockfile (package-lock.json) is verbose and merge-conflicts often. And npm doesn't natively support monorepo workflows as well as pnpm or Yarn.

None of those weaknesses outweigh npm's biggest strength: it's already there. For a hobby project, an open-source library, or a team you're not 100% sure about, npm is the safe default. Reach for pnpm or Bun when you want the speedup or the monorepo support.

Code

What you get the moment Node.js is installed·bash
# Install Node via Homebrew (or use nvm, fnm, mise, asdf, ...)
brew install node

# npm is bundled — you have it for free
node --version    # v22.x.x or v24.x.x
npm --version     # 10.x or 11.x

# npx (one-off package runner) is also bundled
npx --version

External links

Exercise

Run 'npm --version' and 'node --version'. If you don't have Node, install it via Homebrew ('brew install node'). Then create a scratch directory and run 'npm init -y' — read the package.json that gets created. Every field has a meaning; this is the file every JS tool revolves around.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.