How to efficiently update your npm dependencies ?
If you want to keep your project secure, fast and enjoy the latest features of all your dependencies, it's important to keep them regularly up-to-date. I suggest you to update them once every month or at least once every 2 months. By doing so, you'll face less breaking changes at the same time and keep a better control of the changes you'll introduce.
🔒 About safety, you can find in this very good article what could happen if your dependencies are not updated when a security issue is found and fixed. To avoid this, yarn and npm both have a cli command that will show you the dependencies you're using that are not up-to-date with their latest security patches:
yarn audit or
npm audit. And finally, this page contains the list of the latests security advisories.
#Know your dependencies
What are they used for ? Do you really need them ? Are they correctly ordered between dependencies and devDependencies ? This may sound a bit obvious but if you're working on a project that you haven't initialized or where people were free to add dependencies, I'm pretty sure that you don't have a full control of what you're using.
So the first step is to check if your dependencies are really used. If some of them aren't, well... Just remove them by running
yarn remove your-dependency.
Then, you can check if you really need a dependency for the usage you're doing of it. For example, in one of my client's project, I found that we've installed a big dependency and we were using only one function of it... So instead of keeping it up-to-date and having it included in our final bundle, I simply removed it and recreate the function we needed directly in the project !
#What are the changes ?
To correctly update your dependencies and being able to adapt your code with the potential breaking changes, it's important that your dependencies contain a CHANGELOG file, some documentation or even better a migration guide.
Usually, a lot of dependencies have a CHANGELOG.md file at the root of their repository. This file contains the list of the changes (bugfixes / features) released with each new version. If the updates follow the semantic versioning, it'll be easier to predict if an update will be easy or not. When it comes to breaking changes, check if the CHANGELOG contains enough information about how to deal with it. The React's CHANGELOG is a very good example of how this should be done.
Sometimes the repository doesn't contain a CHANGELOG file but is using the releases tab in github to document the versioning.
For some big updates, you can even find a migration guide that explains you what are the changes and how to deal with them. Here is a good example with the migration to the v4 of styled-components.
#Test, test and test again
Each time you'll update a (group of) dependency, you should run your tests (if you have some 😃), check that your builds are still working, do some manual test on your application, ...
Even on patches and minors update, I suggest you to check that it doesn't break anything... Sometimes those updates are marked as backward compatible but depending on the usage you've of them, it may break things.
If you know your application, just follow your instinct when you update a dependency. For example if you remember that you have an advanced usage of it on a specific page, go and check it first 🙂.
#Upgrade following your package.json versions
By default, Yarn allows you to upgrade your dependencies in an interactive way. You just have to run
yarn upgrade-interactive and you'll be prompted with all the possible updates (that follows the versions you've set in your package.json file) you can do. See documentation.
yarn upgrade-interactive interface
In your console, your dependencies will be splitted between dependencies and devDependencies. For each possible update, yarn gives you the version you've set in the package.json, the current version you're upgrading from, the version you're upgrading to and a link to website (or repository) of the dependency.
Then, you can move from one library to another by using arrow up or arrow down. To select the libraries you want to update, you have to press space in front of the selected one. And finally, to execute the upgrades, you just have to press enter. By doing it, the new versions will be installed and your yarn.lock file will be updated accordingly - as you'll still match the versions specified in your package.json file, this file won't be updated.
As you may have noticed, yarn is colorizing the possible updates into 3 colors: green, yellow and red.
All the libraries that are in green can be updated safely without really looking at the changelogs (it only concerns patches updates)... So far, I haven't faced any issue when I updated green dependencies. So usually, I select all of them and update them together.
Yellow updates are related to minor updates. So normally, you should be able to update them without any problem but i'd suggest you to do it one by one and by running tests after each update. It'll take time but it'll be safer...
Red updates are for major updates. So somehow it means that the version you've specified in the package.json is really permissive. It can also be related to local dependencies (and so yarn hasn't access to the repo to check the versions). For sure here, you have to update them one by one and have a real look at the changelogs !
#Upgrade to higher versions
Using yarn, the
yarn upgrade-interactive command line only shows the upgrades that follow the package.json file declaration. That said, as stated in the documentation, you can add the
--latest option, this will show you all the possible upgrades even if they don't follow the versioning you've set in your package.json (they'll be displayed in red).
Here again, thanks to the interactive interface, you'll be able to choose which dependency you want to update. By selecting them and updating them, it'll automatically update your package.json and install the new version of the dependencies !
Unfortunately, npm doesn't integrate natively any upgrade tool. So to do it, you need to install a new global dependency. And here is a good one: npm-check. You can use it by running the following:
npm install -g npm-check. And then, in your repository :
npm-check -u (
-u options activate the interactive update).
npm-check interface (source: https://www.npmjs.com/package/npm-check)
In npm-check, updates are organized by type of updates : patch / minor / major / non semver. So here again, you can select all the patches and update them together. And then you'd better run the minor / major updates one by one. npm-check also provides you a link to the website of each dependency or at least to its repository.
You can move from one library to another by using arrow up or arrow down. To select the libraries you want to update, you have to press space in front of the chosen one. And finally, to execute the upgrades, you just have to press enter.
Each time you'll update dependencies, it'll automatically install the new version and update your package-lock.json file accordingly.
Many more options are available with npm-check so I suggest you to have a look at them.
If you liked this article, please share it on Twitter.