Bitdoze Logo

How to Update All Node.js Dependencies to Latest Version

Learn how to update all Node.js dependencies with npm-check-updates, interactive mode, doctor mode, and supply chain security best practices.

DragosDragos19 min read
How to Update All Node.js Dependencies to Latest Version

Node.js has a large ecosystem of packages you can pull into your projects. These packages are your dependencies, managed by npm (Node Package Manager) or alternative tools like pnpm, Yarn, and Bun.

Dependencies live in a file called package.json at the root of your project. This file tracks your project’s name, version, scripts, and every dependency it needs. Here’s a typical entry:

"dependencies": {
  "express": "^4.17.1"
}

The version number uses semantic versioning prefixes. The ^ prefix means “any version compatible with 4.x.x” – so ^4.17.1 accepts anything from 4.17.1 up to (but not including) 5.0.0. The ~ prefix is more restrictive, accepting only patch updates within the same minor version (e.g., ~4.17.1 means 4.17.x). An exact version like 4.17.1 locks to that specific release.

To install dependencies, run npm install in your terminal. This downloads packages from the npm registry into a node_modules folder.

If you don’t have Node.js installed yet, check out how to install Node.js using NVM – it’s the recommended way to manage multiple Node.js versions. Fish shell users can also see how to use NVM with Fish Shell.

Keeping those dependencies updated is important. Outdated packages accumulate security vulnerabilities, miss performance improvements, and eventually become incompatible with each other. This guide covers how to update Node.js dependencies safely in 2026.

Why you should update Node.js dependencies regularly

Regular dependency updates give you:

  • Security patches for known vulnerabilities
  • New features and API improvements
  • Performance optimizations from upstream changes
  • Bug fixes that resolve issues in your codebase
  • Better compatibility with the latest Node.js versions

In 2025 alone, security researchers flagged nearly 455,000 malicious packages on npm. Supply chain attacks are a real and growing threat. Running outdated dependencies exposes your project to known exploits that have already been patched upstream.

But updating isn’t risk-free.

Breaking changes

Major version bumps (e.g., Express 4.x to 5.x) can include breaking API changes. Always check the changelog before upgrading across major versions. A function you rely on might have been renamed, removed, or its parameters changed. Use a staged update strategy (patch first, then minor, then major) to isolate problems.

With the right tools and workflow, you can update without breaking production.

Understanding semantic versioning (semver)

Before getting into update commands, understand how npm version numbers work. Every package follows the MAJOR.MINOR.PATCH convention:

Version Part What Changes Example
MAJOR (1st) Breaking changes, incompatible API changes 4.17.15.0.0
MINOR (2nd) New features, backward-compatible 4.17.14.18.0
PATCH (3rd) Bug fixes, security patches, backward-compatible 4.17.14.17.2

Semver prefix quick reference

^4.17.1 (caret) – allows minor and patch updates within 4.x.x. This is the npm default. ~4.17.1 (tilde) – allows only patch updates within 4.17.x. 4.17.1 (exact) – locks to that exact version. No automatic updates. >=4.17.1 – any version at or above 4.17.1.

Most package.json files use ^ prefixes. This means running npm install will pull the latest compatible patch or minor release – but never a new major version. To jump across major versions, you need a tool like npm-check-updates.

How to update all Node.js dependencies using npm-check-updates

npm-check-updates (ncu) is the go-to tool for bumping dependencies to their latest versions. It rewrites the version numbers in your package.json without installing anything. You run npm install afterward. As of 2026, ncu is at v22+ and requires Node.js ^20.19.0 || ^22.12.0 || >=24.0.0 with npm >=10.0.0.

1. Install npm-check-updates

You have two options: global install or npx.

Important: npx ncu does not work

Use the full name npx npm-check-updates. The short form npx ncu resolves to a completely different (unrelated) package on npm. This is a common mistake that leads to confusing errors.

2. Check which packages are outdated

Run ncu in your project directory to see which packages have newer versions available:

ncu

Output looks like this:

 express          ^4.21.0  →   ^5.1.0
 cors             ^2.8.5   →   ^3.0.0
 dotenv           ^16.4.5  →   ^16.4.7
 uuid             ^9.0.1   →   ^11.1.0

You can also use npm’s built-in command as an alternative:

npm outdated

The difference: npm outdated shows what’s available within your current semver ranges. ncu shows the absolute latest versions regardless of semver constraints – including major version jumps.

3. Update package.json to latest versions

To rewrite package.json with the latest version numbers:

ncu -u

This updates the version strings in package.json but does not install anything yet. You’ll see output like:

Upgrading /home/user/myproject/package.json
[====================] 5/5 100%

 express     ^4.21.0  →   ^5.1.0
 cors        ^2.8.5   →   ^3.0.0
 dotenv      ^16.4.5  →   ^16.4.7
 uuid        ^9.0.1   →   ^11.1.0
 morgan      ^1.10.0  →   ^1.10.1

Run npm install to install new versions.

4. Install the updated packages

Now install the new versions:

npm install

This downloads the updated packages into node_modules. Run your tests afterward to make sure nothing broke.

Quick reference: npm-check-updates commands

Command What It Does
ncu Show outdated packages (read-only)
ncu -u Update package.json to latest versions
ncu -i Interactive mode – pick packages one by one
ncu --doctor -u Iteratively test upgrades to find breaking changes
ncu --target patch Only suggest patch-level updates
ncu --target minor Only suggest minor + patch updates
ncu --filter express Only check specific packages
ncu --reject react Exclude specific packages from updates
ncu --dep prod Only check production dependencies
ncu --cooldown 7 Skip packages published less than 7 days ago

Using interactive mode to update selectively

When you don’t want to update everything at once, use interactive mode:

ncu -i

This displays a list of outdated packages with checkboxes. Use arrow keys to navigate and the spacebar to toggle individual packages on or off. Press Enter to apply your selections.

Interactive mode is useful when:

  • You want to update a few safe packages first and handle risky ones later
  • You’re doing a triage pass on a project with many outdated dependencies
  • You want to skip packages that you know have breaking changes

Organize output by update type

Add --format group to organize the list by major, minor, and patch updates:

ncu -i --format group

This makes it easy to quickly approve all patch updates and skip major ones.

Using doctor mode for safe major upgrades

Major version upgrades are the riskiest part of dependency updates. Doctor mode handles this automatically by iteratively upgrading packages and running your test suite to find exactly which upgrade breaks things.

ncu --doctor -u

Here’s how it works:

  1. Runs your test suite first to establish a baseline (tests must pass initially)
  2. Upgrades all packages to their latest versions
  3. Runs tests again
  4. If tests fail, it uses a binary search approach. It reverts half the upgrades, tests, and narrows down until it finds the specific package causing the failure.
  5. Keeps all passing upgrades and reverts only the breaking one
  6. Repeats until all packages are tested

Recommended for major upgrades

Doctor mode is the safest way to handle large version jumps. Instead of guessing which package broke your app, the tool pinpoints it for you. The catch: you need a working test suite, and it requires the -u flag to actually apply changes.

Available since ncu v8, doctor mode has become a standard part of dependency update workflows. It works with any test runner that exits with a non-zero code on failure.

Targeting specific update levels with ncu

Sometimes you don’t want the latest of everything. ncu’s --target flag lets you control how aggressive updates are:

# Only patch updates (bug fixes, security patches)
ncu --target patch

# Minor + patch (new features, no breaking changes)
ncu --target minor

# Stay within current semver range (same as what npm install would do)
ncu --target semver

# Pre-release versions tagged @next
ncu --target @next

# Highest version number regardless of dist-tag
ncu --target greatest

A staged approach works well in practice:

  1. ncu --target patch -u && npm install && npm test – safe, apply immediately
  2. ncu --target minor -u && npm install && npm test – usually safe, test after
  3. Handle major upgrades individually with doctor mode

You can also filter which packages to update:

# Only update specific packages
ncu --filter express,cors

# Update everything except specific packages
ncu --reject react,react-dom

# Use wildcards
ncu --filter "@types/*"

# Only production dependencies (skip devDependencies)
ncu --dep prod

Updating dependencies with pnpm, Yarn, and Bun

npm-check-updates works with any package manager (it only modifies package.json). But each package manager also has its own built-in update commands:

All of these tools respect package.json version ranges by default. To jump across major versions, you typically need the --latest flag (pnpm, Bun) or a tool like ncu.

Supply chain security: dependency cooldowns and release age

This section didn’t exist when this article was first written. Supply chain security has since become a core part of dependency management.

Supply chain attacks on npm have exploded. In 2025, security researchers identified nearly 455,000 malicious packages on the npm registry. Attackers hijack popular package names, inject malware into legitimate updates, or typosquat common package names. The Axios compromise in March 2026 showed that even widely-trusted packages aren’t immune.

The defense: dependency cooldowns, refusing to install packages that were published too recently.

Setting a minimum release age in .npmrc

Starting with npm 11.10.0 (February 2026), you can configure a min-release-age in your .npmrc file:

min-release-age=7d

This tells npm to reject any package published less than 7 days ago. The logic is simple: if a package update contains malware, it will likely be detected and removed by the community within a few days. Waiting a week gives security researchers time to flag malicious releases.

Using cooldown with npm-check-updates

ncu v20+ auto-detects cooldown settings from your package manager config:

  • npm: reads min-release-age from .npmrc
  • pnpm: reads minimumReleaseAge from .npmrc
  • Yarn Berry: reads npmMinimalAgeGate from .yarnrc.yml

You can also set it directly with ncu:

ncu --cooldown 7

This skips any package published less than 7 days ago when checking for updates.

npm v12 coming July 2026

Major security changes are landing in npm v12. By default, install scripts from dependencies will not run without explicit approval. Other defaults include --allow-git: none and --allow-remote: none. To prepare:

  • Run npm approve-scripts to whitelist trusted packages now
  • Run npm deny-scripts to explicitly block suspicious ones
  • Test your CI/CD pipelines with these restrictions before v12 drops

These changes stop a common attack vector where malicious packages execute arbitrary code during npm install.

Protect your projects now

Even before npm v12, you can take these steps today:

  1. Add min-release-age=7d to your .npmrc
  2. Use ncu --cooldown 7 when checking for updates
  3. Run npm audit regularly to catch known vulnerabilities
  4. Set up automated dependency updates with Dependabot or Renovate (covered below)

If you’re deploying Node.js apps with Docker, see our guide on top Docker commands you need to know for container security best practices.

Running security audits with npm audit

After updating dependencies, always run a security audit:

npm audit

This checks your installed packages against the npm security advisory database and reports known vulnerabilities. Output includes the severity level (low, moderate, high, critical), the affected package, and the path through your dependency tree.

To automatically fix vulnerabilities:

# Fix within semver ranges (safe)
npm audit fix

# Fix with major version bumps (may break things)
npm audit fix --force

npm audit caveats

npm audit has a signal-to-noise problem. It often flags vulnerabilities in transitive dependencies (packages your packages depend on) that don’t actually affect your runtime. A “high severity” audit finding in a dev-only package that only runs during testing is different from one in your production dependency path.

Use npm audit --omit=dev to focus on production dependencies. Don’t panic over every audit finding. Evaluate whether the vulnerable code path is actually used in your project.

Automating dependency updates with Dependabot and Renovate

Manual updates work for small projects. For anything with CI/CD, automate it.

Dependabot

GitHub’s built-in dependency update bot. Configure it in .github/dependabot.yml:

version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 10
    reviewers:
      - "your-github-username"

Dependabot creates pull requests automatically when new versions are available. It’s free for all GitHub repositories and requires zero infrastructure.

Renovate

Open source, self-hostable, and far more configurable. Advantages over Dependabot:

  • Grouping: Combine multiple related updates into a single PR (e.g., all @types/* packages)
  • Automerge: Auto-merge patch updates that pass CI
  • Schedules: Run updates only during business hours
  • Custom rules: Match packages by pattern, version type, or source

Configure via renovate.json in your repo root:

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:base"],
  "packageRules": [
    {
      "matchUpdateTypes": ["patch"],
      "automerge": true
    },
    {
      "matchPackagePatterns": ["@types/*"],
      "groupName": "type definitions"
    }
  ]
}

Use Dependabot if you’re on GitHub and want something that works with zero config. Use Renovate if you need grouping, automerge, or finer control over update behavior.

Best practices for updating Node.js dependencies safely

Use a staged update strategy

Don’t update everything at once. Work in stages:

  1. Create a branch: git checkout -b deps-update
  2. Update patch versions first: ncu --target patch -u && npm install && npm test
  3. Update minor versions: ncu --target minor -u && npm install && npm test
  4. Handle major versions individually: ncu --doctor -u
  5. Commit and merge

This isolates problems. If something breaks, you know it’s in the most recent stage.

Create a .ncurc configuration file

Save project-specific ncu settings in .ncurc.json:

{
  "reject": ["mongoose", "sequelize"],
  "target": "minor",
  "upgrade": true
}

This keeps certain packages pinned (maybe you know they have breaking changes) and sets a default update level. Run ncu without flags and it reads this config automatically.

Handle peer dependency conflicts

When packages require specific versions of shared dependencies, conflicts arise:

# Check for peer dependency issues
ncu --peer

If you hit peer dependency errors after updating, try:

npm install --legacy-peer-deps

This tells npm to use the older, more lenient dependency resolution. It’s a workaround, not a fix, but it unblocks you while you sort out the conflict.

For a more permanent solution, use the overrides field in package.json to force specific versions:

{
  "overrides": {
    "some-transitive-dependency": "^2.0.0"
  }
}

General workflow tips

  • Always work in a git branch when updating dependencies
  • Update frequently, weekly or monthly, to avoid accumulating debt
  • Read changelogs for major version updates before applying them
  • Pin exact versions in production, use ranges for dev tools
  • Set up CI to run tests on dependency update PRs
  • Use min-release-age in .npmrc for supply chain protection

Make sure your git workflow is solid. Linking GitHub with SSH makes pushing branches and reviewing PRs frictionless.

Conclusion

Updating Node.js dependencies doesn’t have to be scary. The workflow is straightforward:

  1. Check what’s outdated with ncu
  2. Update in stages (patch → minor → major)
  3. Test after each stage
  4. Commit and merge

What’s changed since this article was first published is the security environment. Supply chain attacks are real and growing. Configuring dependency cooldowns, running npm audit, and setting up automated updates with Dependabot or Renovate are no longer optional best practices. They’re baseline hygiene.

Start by adding min-release-age=7d to your .npmrc today. Set up a weekly Dependabot schedule. Use doctor mode when you need to tackle major version jumps.

Install Node.js with NVM Host Node.js Apps with CloudPanel