Update Node Dependencies Automatically, Selectively, or Incrementally

Published

March 14, 2022

Reading time
8 min read
This post is part of my Byte Series, where I document tips, tricks, and tools that I've found useful.

Managing Node Dependencies Can Be Tricky

As you are probably well aware, node dependencies can and do change very quickly. Updating these dependencies can become tricky and cumbersome.

Thankfully there is a node package called npm-check-updates that can help the update process become slightly less painful. With the program you can do the following.

  1. Automatically update all the dependencies
  2. Selectively update the dependencies that you choose
  3. Incrementally update dependencies that don't break your tests

NOTE: There is a native command with npm to show outdated node modules (npm outdated), but its output is static. If you use yarn there is also a native command called yarn upgrade-interactive, but npm-check-updates has those features and many more.

Globally Install

One way to execute npm-check-updates is to install it globally, then you can execute with the ncu command.

npm install -g npm-check-updates
ncu

Running with NPX

Another way to run npm-check-updates is to temporarily install and execute it with npx. The benefit of this approach is that you don't have to have it installed globally. However, the downside is a slower runtime since it always downloads the application before running it.

npx npm-check-updates

NOTE: If you want to learn more about npx there is a free 17 minute Execute npm Package Binaries with the npx Package Runner course on Egghead.

Automatically update all the dependencies

If you run ncu with no parameters (or npx npm-check-updates) the program will scan your project and assess your dependencies and compare those with the latest version of the dependencies. The result is a list of modules and its findings.

No changes are made to your package.json by running ncu. There is a message at the end suggesting running ncu -u to upgrade the recommended versions.

NOTE: If you are interested in how ncu determines which node modules need to be updated, you can reference their detailed documentation from their repository.

ncu
~/github/tag-release main
ncu
Checking /Users/elijahmanor/github/tag-release/package.json
[====================] 24/24 100%
 
chalk ^4.1.2 → ^5.0.1
detect-indent ^6.1.0 → ^7.0.0
inquirer ^7.3.3 → ^8.2.1
log-update ^4.0.0 → ^5.0.0
eslint-config-prettier ^8.3.0 → ^8.5.0
lint-staged ^12.3.4 → ^12.3.5
 
Run ncu -u to upgrade package.json

Running ncu -u to Update Dependencies

After running the previous ncu command, you can follow up (or skip the previous step) by running ncu -u (shorthand for ncu --upgrade) to automatically update your package.json with the latest versions. However, this stop only updates your package.json, it does not actually install those modules, you'll need to follow up with npm install if you want to do that. There will be a message at the end of the command to remind you of this step.

NOTE: This will update ALL of your node dependencies to the latest version. If you don't want this behavior, then you might prefer the Selectively update the dependencies that you choose section.

ncu -u
~/github/tag-release main
npx -u
Checking /Users/elijahmanor/github/tag-release/package.json
[====================] 24/24 100%
 
chalk ^4.1.2 → ^5.0.1
detect-indent ^6.1.0 → ^7.0.0
inquirer ^7.3.3 → ^8.2.1
log-update ^4.0.0 → ^5.0.0
eslint-config-prettier ^8.3.0 → ^8.5.0
lint-staged ^12.3.4 → ^12.3.5
 
Run npm install to install new versions.

Installing the Dependencies that were Updated

As the previous step mentioned, you'll need to manually npm install after running ncu -u to actually install the node modules that were updated.

npm install
~/github/tag-release main
npm install
 
added 147 packages, removed 14 packages, changed 11 packages, and
audited 960 packages in 8s
 
104 packages are looking for funding
run `npm fund` for details
 
found 0 vulnerabilities
 

Selectively update the dependencies that you choose

Instead of installing the latest version of ALL of your dependencies, you may instead, wish to selectively pick which node modules you'd like to upgrade. For example, maybe you'd first like to target those modules with only patch upgrades, or only handpick a few modules to start.

Thankfully, you can selectively pick which modules to upgrade by running ncu -i (which is shorthand for ncu --interactive). This mode will prompt you for each node module asking if you would like to upgrade. At the end of the command, it will output which modules were updated in your package.json, but as with the ncu -u command, it is up to you to run npm install to actually install the modules.

ncu -i
~/github/tag-release main
ncu -i
Upgrading /Users/elijahmanor/github/tag-release/package.json
[====================] 24/24 100%
Do you want to upgrade: chalk ^4.1.2 → ^5.0.1? … no
Do you want to upgrade: detect-indent ^6.1.0 → ^7.0.0? … no
Do you want to upgrade: inquirer ^7.3.3 → ^8.2.1? … yes
Do you want to upgrade: log-update ^4.0.0 → ^5.0.0? … no
Do you want to upgrade: eslint-config-prettier ^8.3.0 → ^8.5.0? … yes
Do you want to upgrade: lint-staged ^12.3.4 → ^12.3.5? … yes
 
inquirer ^7.3.3 → ^8.2.1
eslint-config-prettier ^8.3.0 → ^8.5.0
lint-staged ^12.3.4 → ^12.3.5
 
Run npm install to install new versions.

Incrementally update dependencies that don't break your tests

Having the ability to automatically and interactively upgrade modules is great, but it doesn't help you to understand which modules might break your tests or build. Thankfully there is a special --doctor flag that will incrementally update modules while running tests along the way.

The general flow of --doctor mode is the following:

  1. Runs npm install and npm test to make sure everything is passing before upgrading anything
  2. Runs ncu -u to upgrade ALL of the dependencies and installs those upgrades
  3. Runs npm test again to see if they pass. If the tests pass, then exit
  4. If the tests fail, then restore the package.json file
  5. Then start again, but for each dependency, install an upgrade and re-run the tests
  6. If a breaking upgrade is found, save the partially upgraded package.json to the version that worked
ncu --doctor -u
~/github/tag-release main
ncu --doctor -u
Running tests before upgrading
npm install
npm run test
PASS specs/helpers/getRootDirectory.spec.js (7.102 s)
PASS specs/helpers/runCommand.spec.js (7.108 s)
Test Suites: 25 passed, 25 total
Tests: 639 passed, 639 total
Snapshots: 0 total
Time: 14.264 s
Ran all test suites.
 
Upgrading all dependencies and re-running tests
ncu -u
npm install
npm run test
Tests failed
Identifying broken dependencies
npm install
npm install --no-save chalk@^5.0.1
npm run test
chalk ^4.1.2 → ^5.0.1
… more output …

Using Another npm script instead of Tests

It's possible that you don't have unit tests in your package, but you'd still like the benefit of the --doctor command. Thankfully, there is a --doctorTest flag that you can pass to define your own script that will be executed after the upgrade of each dependency. For example, if you'd like to test the status of your build you could pass --doctorTest="npm run build".

ncu --doctor --doctorTest="npm run build" -u
~/github/tag-release main
ncu --doctor --doctorTest="npm run build" -u
… more output …

Explore the Documentation for More Features

There are many more features and options of npm-check-updates that you might like to explore. If this blog post was interesting to you, then it might be worth your time to explore the documentation and explore all that the module provides.

Web Mentions
0
0

Tweet about this post and have it show up here!