⟵back

How to do a large frontend update and stay sane

A few months ago at work, I took on the task of carrying out some frontend package updates. Early on, I realised that one particular library — Material UI — was going to require its own spin-off ticket, as there was a lot to be done. After all, it forms the basis of most of our frontend components; the merge request ended up totalling well over 300 individual changes.

This was a task that we couldn't afford to put off for much longer. As the docs say:

Features become deprecated over time as maintainers make improvements to the APIs. Migrating to these improved APIs results in a better developer experience, so it's in your best interest to stay up to date. Deprecated APIs often become breaking changes in subsequent major versions, so the sooner you migrate, the smoother the next major update will be.

Isolating the task itself was only the first important step, however, and things didn't run as peachily as I'd have liked. If I could do it again, here's how I would approach it differently.

Don't do two dependency-related tickets simultaneously

It seems obvious in hindsight, but I was just too optimistic. The stacked branch approach absolutely has some valid use cases, but for two branches that each have dependency-heavy diffs, it is, sorry to say, a horrible idea.

Every time I switched between the general frontend update branch and the Material UI one, I had to reinstall everything so the frontend builds correctly. Not only does this take up time, it can also muddy the waters regarding what the actual desired version of a certain package is — even more so when there are lots of subpackages involved. It gets even worse when you're even working on other branches in the meantime that are based off the regular develop branch, as was the case for me.

So, if I'm ever in a similar situation again, I will make sure the frontend branch is done and safely merged first before tackling the other one.

Do your research

We didn't just need to update Material UI to a higher version. We also had a few third-party packages that were dependent on this component library and could potentially break due to the migration. There was even a package that hadn't been maintained in several years; obviously that would have become a problem sooner or later. It would not have been compatible with the new Material UI version, but luckily it wasn't very big, and we handled it by writing some new custom code directly into our project.

It would have been nicer to look for an alternative component, but it also would have taken time to find one that met all our requirements... and that's before you even account for the feedback loops for clearing the new aesthetic and explaining further possible trade-offs with the PO.

So in general, this is something to be wary of: don't rely on other people's third-party code.

Be meticulous

When you think of new releases, you might think of the additions; maybe the developers have expanded the possibilities of what you can do with your code. What's more important, though, is the changes. This is why with every new release, every maintainer worth their salt will also provide a list of potential breaking changes.

In the case of this particular update, the props (and in some cases, the shape of the props) changed in ways that did break the way things looked. Material UI provided codemods (code modifications) meant to address these changes. This is where you run a script and it takes care of the code that needs to be changed automatically.

But I guess due to the weight of our project — and, again, the third-party components dependent on it — this was not a seamless transition. The codemod didn't cover everything that needed to be changed (much less the stuff from the packages dependent on Material UI). It was difficult to keep track of everything, especially because from a certain point, some files in GitLab merge requests are collapsed.

Where I work, we are by now generally all expected to integrate AI into our workflow. This was the biggest task so far that I'd used it in, and it was definitely one of those times where it just makes matters worse (there's a nice word for that in German: verschlimmbessern). In an attempt to be more efficient, using AI to try to seek and automate all the changes added an extra layer of complexity. While it referred to docs from the release, a lot of it was contradictory and you could never really be sure you'd done it right. Another thing that made it painful was that our linters and formatters did not enjoy the changes made through the codemods...

Conclusion

These tickets were a thorn in my side for a couple of months, but every experience is an opportunity to learn. The biggest lesson to be taken from this, though, is: keep your damn packages up to date!