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.
- Automatically update all the
dependencies - Selectively
update the dependencies that you
choose - Incrementally
update dependencies that don’t break your
tests
NOTE: There is a native command with npm to show outdated node modules (
npm
), but its output is static. If you use
outdatedyarn
there is also a
native command calledyarn upgrade-interactive
, butnpm-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.
~/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
ncu -u
to Update Dependencies
Running 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.
~/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.
~/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
(which is shorthand for
-incu --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.
~/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:
- Runs
npm install
andnpm test
to make sure everything is passing before upgrading anything - Runs
ncu -u
to upgrade ALL of the dependencies and installs those upgrades - Runs
npm test
again to see if they pass. If the tests pass, then exit - If the tests fail, then restore the
package.json
file - Then start again, but for each dependency, install an upgrade and re-run the tests
- If a breaking upgrade is found, save the partially upgraded
package.json
to the version that worked
~/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 [email protected]^5.0.1
npm run test
✗ chalk ^4.1.2 → ^5.0.1
… more output …
npm script
instead of Tests
Using Another 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"
.
~/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.