Keep npm dependencies up to date
Many developers have been in a situation when their project is stuck because of outdated dependencies. Security vulnerabilities are found in an old dependency. Node.js version is getting out of life, and your project just couldn't compile on the newer version. Many deprecation warnings in the terminal and browser console.
Often forgotten dependencies lead to painful upgrades, more bugs, missed deadlines, and just a very stressful time.
To keep the codebase healthy, dependencies should be kept up to date!
Some pros to keep dependencies always up to date.
- Getting the latest features and the best developer experience.
- Fewer bugs and security vulnerabilities.
- Fewer problems in the future with updates.
- Sometimes faster and smaller bundles.
There are some cons:
- Risk of getting new bugs.
- Risk of getting the bigger bundle.
But the pros outweigh the cons.
Tools permalink
npm outdated
/npm update
permalink
Built-in npm outdated
and npm update
provide very basic experience. npm outdated
shows dependencies, which has newer version. And it shows highest dependency version, which in semver range specified in package.json
.
npm update
updates all dependencies to the highest version, matching the specified semver range (“wanted” column in npm outdated
).
It is not possible to select only a few dependencies, so it installs everything. Sometimes minor version has bugs, and we don't want to update them just yet. With npm update
the only option is to pin the version in package.json
, and then unpin it when the dependency is fixed.
After npm update
npm outdated
shows remaining versions outside the specified semver range. Usually just major versions.
npm update
both updates package.json
and installs new versions (no need to run npm install
).
npm-check-updates
permalink
npm-check-updates
provides a much better experience than built-in tools. It shows version differences more clear than npm outdated
.
Unlike npm update
it updates everything to the latest version ignoring the semver range specified in the package.json
.
npm-check-updates
has an interactive mode, where it asks whether it should update each dependency:
It's not possible to end progress with saving progress in the middle of dependency questions. You'll have to answer to every question, even if you want to update only the first few.
npm-check-updates
updates only package.json
, you need to run npm install
after it.
npm-upgrade
permalink
npm-upgrade
even better experience than npm-check-updates
. It shows same version differences list as npm-check-updates
(it's because npm-upgrade
built on top of it :)). And it provides more functional interactive mode. Interactive mode is main functionality of npm-upgrade
.
Unlike npm-check-updates
you could finish answering questions in the middle of the list and still keep the progress (“Finish update process” option).
npm-upgrade
provides a quick way to see changelog for each dependency. It tries to find a changelog in the repository, or “Release” page on Github. Sometimes it fails to do so, but at least it will open the repository, and you can find changelog yourself.
npm-upgrade
updates only package.json
, you need to run npm install
after it.
npm-check
permalink
npm-check
has a convenient interactive mode. It groups versions (major, minor, patch, non-semver), and unlike previous tools you can go through the list with arrow keys and select dependencies with a space key.
npm update
both updates package.json
and installs new versions (no need to run npm install
).
How I update dependencies permalink
Most of the time I use just npm-upgrade
because it allows selectively update dependencies and easier access to changelogs. Sometimes I use npm-check
.
I prefer to update dependencies every two weeks on Monday. Updating on Monday gives enough time to catch something weird or some regression, and have a calm weekend :) 99% of the time, there are no issues after an update.
Usually, I update dependencies in a few rounds:
- All patch versions, and minor versions of
devDependencies
. It's unlikely something will break. - Then I update minor versions of regular
dependencies
. I try to group updates. E. g. update Babel and all Babel plugins in a single round. Or ESLint and all it's plugins, etc. - Finally major versions. Usually, one major version at a time, unless major versions have breaking changes, which shouldn't cause any problems for my project (e. g. dependency dropping support for some old Node.js version).
Almost after every round I run tests and check in browser (for client-side projects) areas that could be affected by just updated dependencies.
I commit changes after every round. If new dependencies cause problems, then it would be easier to find the cause, and no need to redo previous rounds.
After updates are done, I run tests again and check all affected areas in the browser, if applicable. Clean Git history by merging all commits into one.