Why upgrade dependencies?

Keep dependecies up to date to get bug and performance fixes, not features.

Why should we upgrade dependencies in our projects?

My wife certainly does not see any value in upgrading an application on her phone or computer. She strongly believes the operating system updates only break what is working already. (Do not tell her that iOS 7 is auto updating apps!)

Updating customer facing applications is risky. There are too many features pushed at once, without exhaustive testing, often leading to my data being corrupted, settings getting lost, etc. On the other hand, updating 3rd party dependencies used by my project should not be that risky. Updating to later version also has a potential and largely invisible benefit: most of the changes between versions are bug fixes and performance improvements, not new features.

Let us look at a popular javascript library lodash. I use it in most of my nodejs projects. It saves me huge amounts of time - literally a priceless collection of utilities. Lodash releases new updates fairly regularly - about once a month. There is a 6 month pause right now while the team preps the new major release with tons of new features.

Let us look at the lodash changelog. I will ignore the current work in progress (v3.0.0-pre), and will only count the releases up to and including the current (v2.4.1) version. A release changelog lists each item, and I will classify every item as a feature, fix or misc. Misc is a catch-all for everything that is not a new feature or a bug/performance fix.

For example, v2.4.1

  • fix - Ensured bindData is properly cloned
  • fix - Ensured _.isEqual correctly compares objects with shared property values containing circular references
  • fix - Optimized .partial & .partialRight
  • misc - Reached ~100% code coverage

Release v2.4.1 has no new features, 3 fixes (2 bugs, 1 performance) and 1 misc item.

In other releases, I will count as 1 feature any like starting with Added or Made, even if there are several functions listed. Since this is a new addition, you are not using it, so there is no sense in counting new methods separately. Number of features could go up if we count each new function separately, but so could the number of fixes: some of the fix items listed multiple functions.

If we count backwards to the very first release v0.1.0 (single misc item), we arrive at the following table (I will skip 0 values to highlight holes).

version   features   fixes   misc
---------------------------------
2.4.1                  3      1
2.4.0        5
2.3.0        1        11
2.2.1                  2
2.2.0        1         3
2.1.0        3         5
2.0.0        7         8      7
1.3.1                  4
1.3.0        5        25      2
1.2.1        1         3      1
1.2.0        3         7      2
1.1.1                  1      1
1.1.0        4         6      1
1.0.1        1         5      1
1.0.0        5        10      1
0.10.0       2         7
0.9.2        5         2
0.9.1        1         3
0.9.0        1         6
0.8.2        1         4
0.8.1                  2
0.8.0        3         4
0.7.0        3        11
0.6.1                  2
0.6.0        3         5
0.5.2                  4
0.5.1                  1
0.5.0        6        10
0.4.2        1         3
0.4.1                  2
0.4.0        4         9
0.3.2        1         3      2
0.3.1        1         3
0.3.0        5         4
0.2.2        1         4
0.2.1        2         3
0.2.0        8        10      1
0.1.0                         1
-------------------------------
total       84       194     21

These are very impressive numbers! They do show that most of the code changes are under the hood and are not new features. Even major releases like 1.0.0 and 2.0.0 include lots of non-feature work.

Since I want to take advantage of the work every 3rd party dependency is doing, I monitor out of date dependencies using david-dm. Most of my projects have badges showing if production or dev dependencies are behind. If any dependencies are behind, I quickly update using next-update which installs an update, runs my tests and then keeps the update only if tests pass.

next-update

I also run an anonymous stats when people try upgrading Nodejs modules using next-update at http://next-update.herokuapp.com/. You can quickly lookup any package to see success rates across a matrix of versions.

next-update stats website

You can read more about the actual logic behind next-update in this presentation.