cheat sheet
ncu
The ncu CLI from npm-check-updates rewrites package.json to bump dependency versions — interactive mode, filters, doctor rollback, and workspaces support.
ncu — npm-check-updates CLI
What it is
ncu is the binary shipped by the npm-check-updates package. It scans the dependency ranges in your package.json and rewrites them to newer versions — within the existing semver constraint or beyond it (across major versions) if you ask. Unlike npm update, which respects the existing ^/~ ranges, ncu rewrites package.json itself so the new ranges become the baseline.
After ncu -u, you still run npm install (or pnpm install / yarn install / bun install) to update the lockfile and node_modules. Reach for ncu when you want a deliberate batch dep refresh — quarterly cleanup, pre-release audit, post-incident triage. For day-to-day, npm update or a bot like Renovate / Dependabot is usually sufficient.
Install
ncu is the binary in the npm-check-updates package. Install globally for ad-hoc CLI use, or per-project for CI parity.
npm install -g npm-check-updates
Output: added 1 package; ncu on PATH
pnpm add -g npm-check-updates
Output: added npm-check-updates globally
bun add -g npm-check-updates
Output: added npm-check-updates globally
One-off without install:
npx npm-check-updates
Output: prints upgrade table (does NOT modify package.json without -u).
Per-project install:
npm install -D npm-check-updates
npx ncu --version
Output: prints installed ncu version (currently 17.x)
Day-to-day commands
| Command | What it does |
|---|---|
ncu | Print upgrade table. Does not modify package.json. |
ncu -u (or ncu --upgrade) | Apply the upgrades to package.json. Run npm install after. |
ncu -i (or ncu --interactive) | Prompt to select which packages to upgrade. |
ncu --target minor | Bump within minor + patch only. |
ncu --target patch | Bump patch only. |
ncu --target latest | Bump to absolute latest (includes major). Default. |
ncu --target greatest | Bump to greatest version including pre-releases (alpha/beta). |
ncu --filter <names> | Only consider matching packages. Glob, regex, or comma list. |
ncu --reject <names> | Skip matching packages. |
ncu --workspaces (-ws) | Apply across all workspaces. |
ncu --root | Include the root package.json with --workspaces. |
ncu --doctor -u | Try each upgrade, run tests, roll back failures. |
ncu --peer | Consider peer-dep constraints when picking targets. |
ncu --jsonAll | Machine-readable output. |
ncu --errorLevel 2 | Exit non-zero if upgrades are available (CI gate). |
Common scenarios
Safe minor + patch upgrade
The lowest-risk mode — patches and minors only, by definition backward-compatible per semver.
ncu --target minor
Output: prints the upgrade table; nothing modified yet.
ncu --target minor -u
npm install
npm test
Output: package.json rewritten with the bumped ranges; npm install updates the lockfile and node_modules; tests verify nothing broke.
Major upgrade with prompts
For larger refreshes, use -i to pick which majors to take. Each row shows current → target.
ncu -i --target latest
Output:
? Choose which packages to update (a to select all, i to invert)
❯ ◯ react 18.2.0 → 19.0.0
◯ react-dom 18.2.0 → 19.0.0
◉ vite 5.0.0 → 6.0.0
◉ @types/node 18.18.0 → 22.0.0
◯ next 14.0.0 → 15.0.0
After confirming, package.json is updated for the selected subset.
Per-package filter
ncu --filter react,react-dom
Output: only react and react-dom appear in the report.
ncu --filter "/^@types\//"
Output: all @types/* packages (regex syntax — surround with slashes).
ncu --reject "@radix-ui/*,eslint*" --target minor
Output: skip Radix UI and ESLint plugins; bump everything else minor-only.
Doctor mode (try, test, rollback)
--doctor runs upgrades one at a time: bumps a package, installs, runs npm test, and rolls back individual packages that break the suite.
ncu --doctor -u
Output: for each candidate, prints Trying X@old → X@new, runs install + test, then keeps or reverts. Slow (30–120 seconds per dep) but safe for unattended upgrades.
Override the test command for large suites:
ncu --doctor -u --doctorTest "npm run test:unit"
ncu --doctor -u --doctorInstall "npm ci"
Output: uses the specified scripts instead of defaults.
Workspaces support
For npm / pnpm / yarn / bun workspaces:
ncu --workspaces -u
Output: upgrades all workspace package.json files in lock-step.
ncu --workspaces --root -u
Output: also upgrades the root package.json (root is excluded by default).
Machine-readable output
For scripted pipelines:
ncu --jsonUpgraded
Output:
{
"react": "^19.0.0",
"vite": "^6.0.0"
}
ncu --jsonAll
Output: full report including unchanged packages.
CI gate — fail if outdated
ncu --errorLevel 2
Output: exits non-zero if any dep is outdated. Useful as a pretest or as a scheduled CI job.
Useful flags
| Flag | Purpose |
|---|---|
-u, --upgrade | Apply changes to package.json. Without this, ncu is read-only. |
-i, --interactive | Multi-select prompt. |
--target <type> | latest (default), greatest, minor, patch, newest. |
--filter <names> | Limit packages considered (glob, regex, csv). |
--reject <names> | Inverse of --filter. |
--filterVersion <range> | Only packages currently matching a version pattern. |
--peer | Honour peer-dep constraints. |
--workspaces (-ws) | Apply across all workspaces. |
--root | Include root with --workspaces. |
--deep | Recurse into nested package.json files. |
--doctor | Try-test-rollback workflow. |
--registry <url> | Override registry (handy for mirrors). |
--concurrency <n> | Parallel registry requests (default 8). |
--packageManager <pm> | npm / yarn / pnpm / bun. Auto-detected. |
--silent | Suppress non-error output. |
--jsonAll / --jsonUpgraded | Machine-readable output. |
--errorLevel <n> | Exit code when upgrades exist (CI gate). |
Configuration
Lock long-term policy in .ncurc.json (or .ncurc.yaml, .ncurc.js) at the project root:
{
"target": "minor",
"reject": [
"@types/*",
"eslint*",
"react",
"react-dom"
],
"workspaces": true,
"packageManager": "pnpm"
}
ncu -u then uses these defaults. Override per-run with explicit CLI flags.
For workspace-aware repos, the root .ncurc.json applies to every workspace package; per-package .ncurc.json files override.
Common pitfalls
ncuwithout-udoes nothing. New users see the report, runnpm install, and wonder why nothing changed. The CLI is read-only without-u.ncu -udoes NOT runnpm install. Always follow withnpm install(or your package manager's install). The lockfile won't update otherwise.- Exact pins are still bumped.
"react": "18.2.0"becomes"react": "19.0.0"afterncu -u— same pin style, new version. Use--rejector--filterVersionto preserve specific pins. - Glob vs regex vs CSV.
--filter "react*"is a glob.--filter "/^react/"(with slashes) is a regex.--filter "react,react-dom"is a CSV. Mixing them silently fails. - Peer-dep warnings ≠ broken upgrade. After
npm install, peer warnings are common. They become real failures only if your tests exercise the conflict. @types/*lag the source library. A@types/foomay not have v19 yet even iffoodoes.--target latestand check the report for the reason.- Private packages skip silently. If
.npmrcregistry/auth is missing for a scope, those packages are skipped with a warning buried in the output. Always re-check the report. --doctorruns your tests many times. If your suite has side effects (real DB writes, API calls),--doctorwill run them dozens of times. Use a sandboxed test target.- Network slow.
ncuqueries the registry per package. On slow networks, reduce--concurrencyor run in batches with--filter. - Renovate / Dependabot does the same job continuously. If you already use one of those bots,
ncuis mostly redundant — keep it for one-off audits only.
See also
- Packages-npm: npm-check-updates — package-level reference (Node support, ecosystem, alternatives)
- JavaScript: npm —
npm outdated,npm update,npm audit - JavaScript: package-json — semver ranges, dependencies vs devDependencies, engines
- JavaScript: pnpm —
pnpm update --latestdoes similar work for pnpm workspaces