Node.js – Best Workflow for Keeping Packages Up-to-Date

node.jsnpm

I've recently started developing a project in Node.js. Of course, right now the packages I'm using are pretty up-to-date as I'm starting afresh and using the latest version, but there's a pretty high version turnover rate for most Node.js packages and often certain features will be deprecated or dropped, and of course security vulnerabilities will be fixed.

Since most of my packages are specified using the semantic versioning syntax ^1.2.3 (stick to the given major version number to avoid breaking changes), any important updates beyond the current major version will be lost.

What is a prudent way to ensure that you stay reasonably up-to-date with your dependencies? Is it necessary to put, say, a weekly check for updates to your dependencies into your workflow to make sure you don't fall way behind? And for this reason, would it be a good idea to try and minimize dependencies to minimize the pain of dealing with breaking changes when you necessarily update to newer major versions?

Best Answer

This is the workflow that I currently use for a project with monthly releases.

  • After release, go through the dependencies and update those that have only minor changes and patch updates. Since npm follows semantic versioning, if the authors of the packages did their job fine, this should not break your system.
  • Perform a smoke test and if any dependency is broken, create a task for development to update that dependency. It could be a ticket, it could be a task for your sprint, etc. The point is that updating those not immediate and will require work, so you have to schedule it. Any feedback from your first try will help.
  • Schedule tasks to update dependencies that have major changes.
  • Freeze your dependencies to the newest versions.

The objective is not to have automated updates at all. They might break your system in a way that you don't expect and very likely when you were making other changes, which will not help in figure out what the problem is.

Updating dependencies should be a conscious process, and if any of them break your system, you should be aware of which one.

Minor updates that break and go unnoticed will likely be picked up in your sprint of development or testing, and this is why you do it after release, because you want as much time to detect it and react to that issue before going live.

Note that I actually use this process on a .NET + Nuget dependencies project, but it pretty much applies to Node and npm / bower, Rails + bundle etc.

Finally, you can make use of nice commands that will help you in freezing/unfreezing dependencies, even adding them to your repo. See npm shrinkwrap.