As software engineers, the goal is always to improve the quality of the software we help develop, especially if other engineers are depending on this quality to complete their own projects. We want to be proud of the engineering solutions we devise. These improvements come with a price, however; especially if we change the API, the contract between ourselves and developers that use our libraries or frameworks.
To illustrate this point, I present the story of how the versioning policy for Base Web evolved.
When we started working on the library, we wanted to get it into other developers' hands and collect feedback through usage. Creating the perfect first release was never our intention. Our goal was to learn and iterate quickly, until we had created a library engineers found useful.
It also meant that we released multiple major versions in a short period, to comply with SemVer. In five months, we've released five major versions. Here are a few examples:
This approach worked initially, and we learned a lot about our users, but it wasn't sustainable as more developers at Uber and beyond started using Base Web.
Even the smallest major version release creates work for product teams that depend on your platform, which increases the likelihood you'll introduce regressions.
After the rapid prototyping phase--and once Base Web became popular--it was time to stabilize the library, and create expectations among users anticipating major software releases. For this, we published a public roadmap for Base Web.
In this document are a few key pieces of information:
The new approach came with its own set of challenges. Major updates usually contained small API changes, localized to a handful of components. In the new approach, API changes are accumulated until the next major upgrade, so updating host applications takes more effort. To help product development teams upgrade Base Web, we released codemods for each major update, which allowed automated upgrades to the latest version of the library. You can find an example of a codemod in the Base Web v9 changelog.
We also noticed, that different people had different ideas on what breaking changes meant for them. Would visual updates to components count as a breaking change? Questions like these got addressed in Base Web's Versioning Policy.
To take it further, we updated Base Web for all projects depending on the library for internal users whenever a new release was avilable. In your own projects, be sure you can complete the upgrades without breaking any functionality in the host applications. As Base Web is a React component library, we developed a visual regression test suite for all applications that depend on Base Web.
With this approach, the platform team becomes responsible for maintaining technical debt instead of shifting it to the product teams right away. In fact, this is one of the main reasons we have platform teams.
When you start a new project, it's perfectly acceptable to experiment and learn quickly. No one gets it right the first time. Be upfront about this with your stakeholders, however, so they can plan accordingly.
Balance who needs to address tech debt and when it needs to be addressed. If you serve many product development teams, consider how to reduce the effort necessary to supply them with major versions of your library or platform.
Publish a roadmap. A roadmap is more than just a set of goals for your team. It informs your users about the cadence of your major version releases, and what to expect in them.
Thank you go to Chase Starr, Graham Murdoch, Nadiia Dmytrenko and Vojtech Miksu for contributing to Base Web's release cadence.