SSerguey Asael Shinder
Java coding notes: the JVM, and writing software that lasts

Serguey Asael Shinder: A migration ends when the old path has no callers, not when the new one works

· by Serguey Asael Shinder / Serguey Shinder

GitHub's engineering blog described this week how it moved github.com from CSS-in-JS to CSS Modules. The new approach was working in its design system by December 2024, with server-side rendering 55% faster. The site as a whole ran entirely on CSS Modules only in June 2026. What filled the time in between is the part worth learning from.

The new components were ready early. What was not ready was everything that used the old way of customising them - an sx prop that, at its peak, appeared about 7,760 times across the codebase. GitHub built a wrapper library so that old usages kept working while new code went straight to the migrated components, then converted the codebase package by package. A rotation of eight engineers migrated 6,419 props over six months. The last 895 were removed in three weeks by two engineers with coding agents. Then the themes had to be untangled from the old library before the dependency could finally be deleted - behind a feature flag, like every other step.

I think this is the normal shape of a migration, and it is worth saying plainly because it is so often misjudged. The work that feels like the migration - designing the new path, proving it is better, shipping it - is the first half. The second half is removing the old path, and it has three properties that make it easy to abandon: it has no visible benefit to users, it is spread across teams who did not ask for it, and each remaining usage is individually small.

Serguey Asael Shinder: A migration ends when the old path has no callers, not when the new one works
A migration ends when the old path has no callers, not when the new one works — Serguey Asael Shinder

A few habits make the second half finish instead of fading out:

The detail I keep coming back to is that automation helped most at the end, not the beginning. By the time the last 895 usages remained, the patterns were known and the cases were well understood, which is exactly when a tool - human-written codemod or AI agent - does its best work.