npm-check-updates: Master Your JavaScript Dependencies

npm-check-updates: Master Your JavaScript Dependencies
Managing dependencies in a modern JavaScript project is a lot like gardening: if you don’t prune regularly, weeds (outdated packages, security vulnerabilities, dead code) take over. The default npm update command won’t cut it — it only updates within the existing semver ranges declared in your package.json. To truly control your dependencies, you need npm-check-updates (aka ncu).
What npm update Gets Wrong
Before diving into the solution, let’s understand why the built-in package manager commands fall short.
| Command | What it does | What it MISSES |
|---|---|---|
npm update |
Updates within declared ranges | Won’t cross major versions |
pnpm update |
Same (respects ranges) | Stays within the same major |
npm install pkg@latest |
Forces a version | Tedious across many deps |
npm outdated |
Lists what’s outdated | Doesn’t change anything |
If your package.json reads "express": "^4.18.0", npm update will never fetch Express 5. You’d need to manually edit the file or reach for a dedicated tool.
That’s where npm-check-updates comes in.
What Is npm-check-updates?
npm-check-updates is a CLI utility that updates your package.json to the latest available versions, regardless of your current semver ranges. It preserves existing version operators (^, ~, x, >), but bumps the version number itself.
# In an existing project
npx npm-check-updates
# Or with the shorthand
npx ncu
The output is color-coded: red for major upgrades, cyan for minors, green for patches. Running ncu -u writes the changes to your package.json — it never touches node_modules or your lockfile (npm install handles that).
Installation & Usage
Global install
npm install -g npm-check-updates
# or with pnpm
pnpm add -g npm-check-updates
# or bun
bun add -g npm-check-updates
Once globally installed, the ncu command is available from anywhere.
Using without install (npx/dlx/bunx)
Prefer not to install? No problem:
# npm
npx ncu
# pnpm
pnpm dlx ncu
# bun
bunx ncu
First run
$ ncu
Checking package.json
[====================] 10/10 100%
eslint 7.32.0 → 8.0.0
prettier ^2.7.1 → ^3.0.0
svelte ^3.48.0 → ^3.51.0
astro 1.0.0 → 2.5.0
react 18.2.0 → 19.0.0
Run ncu -u to upgrade package.json
Essential Flags
–target: control the upgrade level
The most useful flag for a conservative update strategy:
# Patch only (safest)
ncu --target patch
# Minor and patch only
ncu --target minor
# Semver: stay within your declared range
ncu --target semver
# Latest (default): go to the newest version
ncu --target latest
With --target minor, your express ^4.18.0 will go to ^4.19.0 at most — no risk of jumping to version 5.
Interactive mode (-i)
When you want to hand-pick which dependencies to update:
ncu -i
This presents a checkbox list (space to toggle, enter to apply). Combined with --format group, it categorizes updates by type (major / minor / patch).
Filter by package (-f / –filter)
# Update only React and React DOM
ncu -u -f react,react-dom
# Exclude specific packages
ncu -u -x typescript,eslint
Doctor mode (–doctor) or (-d)
The most powerful feature for large-scale upgrades:
ncu --doctor -u
Doctor mode works in stages:
- Initial check : installs and runs tests to confirm they pass
- Optimistic upgrade : applies all updates at once
- If tests fail : restores the state, then runs binary elimination
- Report : pinpoints exactly which dependency broke the tests and saves the working upgrades
# With custom commands
ncu --doctor -u --doctorInstall "pnpm install" --doctorTest "pnpm test"
–dep: choose which sections to target
# Production dependencies only
ncu --dep prod
# Dev dependencies only
ncu --dep dev
# Include peer dependencies
ncu --dep dev,optional,peer
–cooldown: supply-chain safety net
# Ignore versions published less than 7 days ago
ncu --cooldown 7d
This flag prevents installing freshly published packages that might contain vulnerabilities or malware — a wise precaution given the supply-chain incidents of recent years.
A Safe, Effective Workflow
Here’s the routine I use on my projects:
# 1. Commit current state
git add package.json package-lock.json
git commit -m "chore: snap before dep update"
# 2. Patches first (safest)
ncu -u --target patch
npm install
npm test
# 3. If OK → commit
git add -A
git commit -m "chore: patch deps"
# 4. Minors next
ncu -u --target minor
npm install
npm test
git add -A
git commit -m "chore: minor deps"
# 5. Majors one at a time
ncu -u -f express
npm install
npm test
For major updates, I prefer handling them one by one with --filter. A major version bump can introduce subtle breaking changes — a changed API signature, different default behavior, a removed polyfill. Doctor mode (ncu --doctor -u) is excellent for automating this detection.
Global Packages Too
npm-check-updates also works for globally installed packages:
# List outdated global packages
ncu -g
# Upgrade all globals in one go
ncu -gu
Great for keeping tools like pnpm, typescript, eslint, or prettier up to date globally.
Works with Every Package Manager
Since ncu only modifies package.json (it doesn’t install anything), it’s compatible with all package managers:
# npm
npx ncu && npm install
# pnpm
pnpm dlx ncu && pnpm install
# bun
bunx ncu && bun install
# yarn
npx ncu && yarn install
Tips & Tricks
.ncurc: configuration file
Create a .ncurc.json at the root of your project for global rules:
{
"target": "minor",
"reject": ["typescript", "eslint"],
"dep": ["prod", "dev"],
"peer": true
}
Recursive monorepo updates
# Walk through all sub-projects
ncu --deep
# or with workspaces
ncu --workspaces
Custom format
ncu --format group,ownerChanged,repo,time
Groups updates by type, with repo owner, GitHub link, and publication date.
Silent exit for CI
ncu --errorLevel 1
Returns exit code 0 when no updates are available — perfect for CI pipelines.
Why I Swear by ncu
npm-check-updates turns a tedious chore (scrutinizing every single dependency one by one) into a fast, controlled, dare-I-say pleasant operation. The ability to separate the decision to update (ncu -u) from the installation (npm install) and testing (npm test) gives you granular control that no other approach offers.
The best strategy? Update often, in small increments. A patch per week beats 50 major bumps the day before a deadline. npm-check-updates makes this discipline feasible without spending hours on it.
npm install -g npm-check-updates
# Try it right now in your project
ncu