🐦 Migrations are the hardest part of design systems work (#75)
I've been working on design systems for 5 years now. The hardest challenge that I've faced has been has been replacing old stuff with new stuff.
Of course, building tools like codemods can simplify the technical part. I'd guess you can use automation to replace 80% of the instances of a deprecated component.
But replacing the last 20% of component instances is nearly impossible without the help of product engineers on consuming teams.
How migrations usually work
Step 1: Build a replacement component
The design systems team builds a replacement component that has feature parity with the old one. If the new component is less feature-rich, it'll be very difficult to prevent product engineers from using the old component without removing it from the codebase.
Step 2: Stop the bleeding
Usually, there are significantly fewer design systems engineers than product engineers in an organization. In order to successfully run a migration, the DS team needs to stop the bleeding.
This means that the DS team needs to create backstops to prevent product engineers from continuing to use the deprecated component. There are many different ways to do this.
Step 3: Use automation to replace as many instances as possible
Once most product engineers have stopped adding new instances of the old component (some people will still use it), then you need to start replacing it with the new one.
You'll probably find some automated way of doing this, like building a codemod or using a tool like Sourcegraph.
Then a couple of engineers will need to run that codemod across the whole product area, which will allow them to replace about 80% of the "not-special" instances of the old component.
Step 4: Realize there's a large chunk of components that need manual replacement
Here's where the migration usually fails. That last 20% is a massive chunk of effort to remove, and it's too much for 1 or 2 engineers to remove, especially if it exists in niche product areas that the design systems engineers aren't familiar with.
This is when product engineers need to start manually replacing old component instances with new ones. It is very very hard to get a design systems migration onto the roadmap of a product engineering team, because removing an old component is never going to be considered as necessary to the business as building a new feature.
So what do we do about it?
Is it OK that we can never fully remove a component? Is it enough to deprecate it and hope that people mostly stop using it to build new features?
Part of me believes that eventually, old code gets rewritten or at least is not touched often enough for it to matter much. Maybe it's perfectly fine to stop maintaining an old component once 80% of its usage has been replaced?
What do you think? Have you seen migrations run smoothly on your team? If so, I'd love to hear about it.
Talk soon,
Mae