The naive migration replaces every #4f46e5 in the codebase with var(--color-brand-primary) in a giant pull request. That PR will not merge. It will block other work, conflict with everything, and fail review.
The pragmatic migration runs old and new in parallel through a token bridge — a layer that maps your legacy values to your new tokens, so both can coexist for as long as the migration takes.
Define the bridge
Build a small file that aliases legacy hex values to new semantic tokens. legacy-blue-500 → color-brand-primary. legacy-spacing-md → space-card-padding. The file is a deprecation map.
Components migrated to the new system reference the new tokens. Components not yet migrated reference the legacy aliases, which still resolve to the right values via the bridge.
Lint old patterns, allow them
Add an ESLint rule (or Stylelint) that flags raw hex values and direct legacy-token references — but at warning level, not error. The team sees the lint output without the build breaking.
Once a critical mass of files are clean, escalate to error. Until then, the warnings are the inventory.
Codemod what you can
For mechanical replacements (hex → token reference, spacing-px → spacing-token), write a jscodeshift transform. Most teams discover 60-80% of the work is mechanical.
Run the codemod per surface, not against the whole codebase at once. Smaller PRs review faster, ship faster, conflict less.
Define the cutover criterion
When does the bridge get retired? Pick a measurable threshold: 95% of components on new tokens, zero new commits referencing legacy aliases for 30 days, lint rule escalated to error.
Without the criterion, the bridge becomes permanent infrastructure. With it, the bridge has a planned end-of-life from day one.
- 01Build a deprecation map that aliases legacy values to new tokens — old and new ship side-by-side.
- 02Lint old patterns at warning level first; escalate to error only after critical mass of files are clean.
- 03Codemod the mechanical 60-80%; reserve human review for the structural decisions.
- 04Define the bridge's retirement criterion at the start so it doesn't become permanent.