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.

bash
npm install -g npm-check-updates

Output: added 1 package; ncu on PATH

bash
pnpm add -g npm-check-updates

Output: added npm-check-updates globally

bash
bun add -g npm-check-updates

Output: added npm-check-updates globally

One-off without install:

bash
npx npm-check-updates

Output: prints upgrade table (does NOT modify package.json without -u).

Per-project install:

bash
npm install -D npm-check-updates
npx ncu --version

Output: prints installed ncu version (currently 17.x)

Day-to-day commands

CommandWhat it does
ncuPrint 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 minorBump within minor + patch only.
ncu --target patchBump patch only.
ncu --target latestBump to absolute latest (includes major). Default.
ncu --target greatestBump 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 --rootInclude the root package.json with --workspaces.
ncu --doctor -uTry each upgrade, run tests, roll back failures.
ncu --peerConsider peer-dep constraints when picking targets.
ncu --jsonAllMachine-readable output.
ncu --errorLevel 2Exit 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.

bash
ncu --target minor

Output: prints the upgrade table; nothing modified yet.

bash
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.

bash
ncu -i --target latest

Output:

text
? 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

bash
ncu --filter react,react-dom

Output: only react and react-dom appear in the report.

bash
ncu --filter "/^@types\//"

Output: all @types/* packages (regex syntax — surround with slashes).

bash
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.

bash
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:

bash
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:

bash
ncu --workspaces -u

Output: upgrades all workspace package.json files in lock-step.

bash
ncu --workspaces --root -u

Output: also upgrades the root package.json (root is excluded by default).

Machine-readable output

For scripted pipelines:

bash
ncu --jsonUpgraded

Output:

json
{
  "react": "^19.0.0",
  "vite": "^6.0.0"
}
bash
ncu --jsonAll

Output: full report including unchanged packages.

CI gate — fail if outdated

bash
ncu --errorLevel 2

Output: exits non-zero if any dep is outdated. Useful as a pretest or as a scheduled CI job.

Useful flags

FlagPurpose
-u, --upgradeApply changes to package.json. Without this, ncu is read-only.
-i, --interactiveMulti-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.
--peerHonour peer-dep constraints.
--workspaces (-ws)Apply across all workspaces.
--rootInclude root with --workspaces.
--deepRecurse into nested package.json files.
--doctorTry-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.
--silentSuppress non-error output.
--jsonAll / --jsonUpgradedMachine-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:

json
{
  "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

  1. ncu without -u does nothing. New users see the report, run npm install, and wonder why nothing changed. The CLI is read-only without -u.
  2. ncu -u does NOT run npm install. Always follow with npm install (or your package manager's install). The lockfile won't update otherwise.
  3. Exact pins are still bumped. "react": "18.2.0" becomes "react": "19.0.0" after ncu -u — same pin style, new version. Use --reject or --filterVersion to preserve specific pins.
  4. 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.
  5. Peer-dep warnings ≠ broken upgrade. After npm install, peer warnings are common. They become real failures only if your tests exercise the conflict.
  6. @types/* lag the source library. A @types/foo may not have v19 yet even if foo does. --target latest and check the report for the reason.
  7. Private packages skip silently. If .npmrc registry/auth is missing for a scope, those packages are skipped with a warning buried in the output. Always re-check the report.
  8. --doctor runs your tests many times. If your suite has side effects (real DB writes, API calls), --doctor will run them dozens of times. Use a sandboxed test target.
  9. Network slow. ncu queries the registry per package. On slow networks, reduce --concurrency or run in batches with --filter.
  10. Renovate / Dependabot does the same job continuously. If you already use one of those bots, ncu is mostly redundant — keep it for one-off audits only.

See also