The Anti-Migration Manifesto
A migration rebuilds working software because a framework, platform, or tool beneath it changed. Much of that work is imposed by foundations the team does not control.
The foundation moves
A migration moves a working application to another framework, language version, library release, or platform. The product may do the same thing before and after. The work can still be necessary, but much of its value is defensive: retaining support, security fixes, or access to an ecosystem.
Product work slows while the foundation is replaced. “Technical debt,” once a name for deliberate shortcuts, often becomes a name for falling behind somebody else's release schedule.
The JavaScript ecosystem offers a familiar history of frameworks, component models, build tools, routers, and state libraries. These tools brought real improvements. They also left applications carrying migrations their users never requested. The React team eventually deprecated Create React App and directed existing users toward other tools.
The foundation moves. The application follows.
What it costs
Frameworks encode decisions. As their authors learn and priorities change, those decisions change too. When a framework reaches through the application, its evolution becomes the application's work. Languages evolve, runtimes remove old behavior, and package ecosystems move with them. An upgrade becomes harder when every package in a large graph must move first. Moving among servers, containers, managed services, and edge platforms can change assumptions about state and networking.
Adopting a foundation means accepting some part of its future schedule. The trade can be worthwhile. It is never free.
Migration work competes with product work and rarely delivers a feature by itself. A new router, runtime, or data layer can differ at the edges the old system had already learned to handle. Teams accumulate practical knowledge about quirks and safe limits; replacing a foundation discards part of it. A migration that stops halfway leaves two architectures and two maintenance paths. The temporary state can outlive the project that created it.
Turn migrations into maintenance
When we control a library and its callers, we can change them together. We prefer direct interfaces, stable formats, and narrow operating-system boundaries. We avoid proprietary platform APIs unless their value justifies the future exit cost.
Ownership does not freeze software. Languages, operating systems, hardware, public protocols, and our own requirements still change. We update code, repair assumptions, and sometimes replace designs. More of the reason and the schedule remain ours.
Maintenance improves a system in place. Migration rebuilds it because an external foundation moved. We want more of our work to be the former.
A new foundation may offer capability, performance, safety, or ergonomics worth the cost. Unsupported software can also become a security and compatibility risk. Those are reasons to migrate. We will rewrite when the product or the system requires it, not merely to synchronize with somebody else's version number.
Own more of the foundation, and more of the schedule becomes yours.