A breaking change needs a migration path
Aliases: migration path · codemod · compatibility alias · compatibility shim
What it is
Change a public prop, remove a default slot, swap a semantic role, and call sites no longer compile or run as written — that is a break. Breaks are allowed. They must ship with a migration path from the old writing to the new: a compatibility alias, a dual export, a runnable rewrite, or a point-by-point map. A break with no path asks every call site to be rewritten by hand on the same day.
The path is how you get across. It is not how version numbers encode the size of the break, and not a prior count of how expensive the call sites are. Those are numbering and pacing. The demand here is only that a walkable route exists between the old world and the new.
Why it happens
Call sites live in other people’s repositories. Once the break ships, the compiler or the runtime errors every unmigrated site at once; consumers have no in-between. A path turns the cut into a sequence: keep the old name working against the new implementation, offer a mechanical rewrite, then close the old name. Compatibility aliases keep unmigrated sites temporarily legal; a codemod makes the rewrite repeatable and reviewable; a mapping table covers semantic shifts a script cannot see (button role becoming a link).
Missing any carrier, the path breaks at that layer: docs without a script get copied wrong; a script without an alias turns every repo that did not run it red on release day; an alias with no close date lets the old writing live forever. The product of a path is a sequence, not the sentence “please upgrade.”
Where it stops holding
An unreleased internal component whose call sites all sit in one repo and can be rewritten in the same commit does not need a cross-package path. Pure additions (optional props, extra variants) are not breaks; inventing migration docs for them is noise. Platform-forced breaks (a system API the OS deleted) are not yours to path; the product follows the system calendar and offers consumers its own mapping. Binary protocols and native SDKs that cannot hot-swap an alias may path as a parallel package name rather than an old export in the same package — the carrier may change; the path may not vanish.
Applying it
- Every breaking item in the changelog names its carriers: how long the alias lasts, what the codemod command is, where the mapping table lives. Missing one, the change does not merge.
- Ship the aliased version first. Run the rewrite green on the main product repo. Then ship the version that drops the alias.
- For semantic shifts a script cannot cover, list old → new by call-site type in the mapping table, each with a runnable example.
- How to check: take one unmigrated old call site and follow only the path, without reading source. It should keep running under the alias, rewrite correctly under the script, and still compile after the close. Any step that requires asking the author means the path is not down yet.
Related
- Same group: R1.05.2 Shipping multiple versions in parallel collapses consistency · R1.05.3 Deprecation needs an explicit date or release
- Nearby: R1.13 Versioning and migration cost · R1.06 Contribution process and governance
- Search terms:
breaking-change migration path·codemod·compatibility alias