Why upgrading software libraries is imperative
June 10, 2020
Applications primarily run on front- and back-end programming languages, including library dependencies. Operating systems and programming languages can be periodically updated to run on the latest version, but what about the many libraries being used in the app’s front and backend? As we all know, it can be quite a daunting task to maintain and individually update a long list of software dependencies like the examples later in this post. Still, it is important to keep them updated.
This post dives into our experience upgrading a complex app with a full software stack and lots of dependencies. We’ll examine the benefits of upgrading, what you will need, and how to go about such an upgrade as simply as possible.
Conflict approach: “Don’t update unless you have to”
While this can be sustainable in the short term, it quickly becomes less applicable in the long run. One important purpose of updates is to (hopefully) protect from new vulnerabilities and cyber attacks. Scenarios arise where particular library fixes are implemented on the latest version, yet require upgrading other libraries to the latest version in a chain. Because upgraded libraries need extensive testing and preparation for new issues, this directly impacts whether the app attempts to resolve an issue.
Therefore, smaller and more frequent updates are more sustainable in the long run. Larger and less frequent upgrades will not only result in unexpected errors, but also require more complete regression testing to deliver a bug-free update. The following reasons justify the necessity of software and library upgrades:
- They apply timely security patches to reduce vulnerabilities and defend from cyberattack
- You can identify deprecated functionality earlier and use alternatives
- They can apply fixes for known bugs in the library
- They’re based on the latest versions of software or library, encouraging stability
In addition, staying on the latest major version yields the benefit of applying minor and patch releases seamlessly without risk. Most software and libraries use semantic versioning, formatted as MAJOR.MINOR.PATCH:
- MAJOR version - Incompatible API changes
- MINOR version - Add functionality with backward compatiblity
- PATCH version - Bug fixes with backward compatibility
So being on the latest major versions of libraries allows applying minor and patch releases without breaking existing functionalities of the app.
The benefits of keeping software and libraries updated include bug fixes, new features, boosted performance, as well as better stability, compatibility, and security measures. We can often ignore upgrades in projects because we don’t perceive significant effects in appearance or usage. But on closer inspection, frequent updates deliver important advantages.
In real-life scenarios, bug fixes and performance optimization of an app often take a higher priority than upgrading libraries. In many cases, this results in a discrepancy between the app’s version and the current version. This discrepancy can lead to the following issues when upgrading libraries:
- Unexpected error handling in new releases
- Unexpected unsupported library dependencies
- Need for complete end-to-end testing due to major version of library upgrade
- Lack of work being visibly completed can lead to a lack of confidence from client
- Difficulty in estimating workload due to major unexpected errors
The following passages offer guidance in how to adequately prepare for these issues.
Much can be learned from preparing for a major upgrade on both a business and technical level. First, a complete list of libraries from the entire app should be compiled. This list should include the latest and current version of the library in the app. Reviewing the changelog of both versions will help identify potential incompatibilities or problems. Visiting the “issue report page” of the library to monitor any version-specific issues is also recommended.
Once you’ve adequately prepared the libraries for upgrading, you can use any method of your choosing to upgrade and maintain the list. Once the roadmap is established, upgrading can commence and compatibility issues that arise can be dealt with as they arise. Finally, thorough end-to-end testing is necessary once the upgrade process is complete.
Below are some examples of software lists you might have for a project (we left out the latest versions for brevity in this post, but it’s helpful to have a column for those too!).
Programming software & servers
|nginx web server||1.12.2||2017-10-17|
|Jetty Java Servlet container||9.2.3||2014-09-05|
Once the app’s software stack and libraries are up to date it’s important to regularly update. The complete upgrade experience can be a rigorous and involved process that includes juggling numerous issues and intensive testing.
From a client’s perspective, a major upgrade project often doesn’t obviously demonstrate improvement to appearance or function. Because it is not recommended to keep outdated software and major upgrades (such as the one described above) are tedious, the following update options are preferable in order to keep software libraries as up-to-date as possible:
- Interval Based: Particular interval periods are implemented to check versions of software. This minimizes frequency of problems while ensuring a manageable gap between the current and latest software version.
- Module Based: Whenever work is performed on any module for new features or bug fixes, software and library versions are reviewed. This allows for relevant libraries to be updated, tested, and deployed along with development changes within the module.
Even if new features and improvements are not pertinent to the new release, frequent upgrades to software and libraries are crucial in order to ensure the most secure and debugged versions. Please feel free to share your methods of managing software updates in a comment!