---
name: migrating-deprecated-apis
description: Detects and replaces deprecated design system APIs, using a machine-readable deprecation table with replacement pointers rather than relying on the model's training data. Use when upgrading a design system version, when a build warns about deprecated usage, when writing code against a library that has had a major release, or when the user mentions migration, upgrade, breaking changes, or a codemod. Applies whenever code is written against a library whose old API outnumbers its new API in public code.
license: CC0-1.0
---

# Migrating deprecated APIs

Across seven evaluated models, deprecated API usage was predicted 25 to 38
percent of the time. The mechanism is not a model defect: old code outnumbers
new code in nearly every repository and in the training corpus, so the first
plausible match is usually the deprecated one.

That makes this a retrieval problem. Another line of prose asking the model to
please use the new API does not move the number. A lookup table does.

## Fill this in first

Maintain this as data, generated from the source, not hand-written prose.

| Removed or deprecated | Use instead | Since | Codemod |
|---|---|---|---|
| `{{OldThing}}` | `{{NewThing}}` | `{{v4.0.0}}` | `{{npx @scope/codemod v4}}` |
| `{{Button color prop}}` | `{{variant prop}}` | `{{v4.2.0}}` | `{{manual}}` |

Three fields carry the weight: the replacement, the version it changed in, and
whether a codemod exists. A deprecation notice without a replacement pointer
just tells the agent it is stuck.

## Procedure

1. **Look up before you write.** Do not rely on recall for any API in this
   library. Check the table.
2. **Check the installed version first.** `{{cat package.json | grep @scope}}`.
   The right API depends on it, and advice for the wrong major is worse than
   no advice.
3. **Prefer the codemod.** If one exists, run it rather than hand-editing.
   Hand-migration across many call sites is where inconsistency enters.
4. **Migrate completely or not at all.** A half-migrated file with both APIs
   is harder to finish than an unmigrated one, and it teaches the next
   generation that both are fine.
5. **Verify.** `{{pnpm typecheck}}`, then grep for the old symbol across the
   whole repo, not just your diff.

## Do not

- Suppress a deprecation warning to make a build pass.
- Introduce the deprecated API in new code because surrounding code uses it.
  Match the target state, not the local state, and say that you did.
- Guess a replacement name from the deprecated one. `Button.color` did not
  necessarily become `Button.colour` or `Button.variant` — look it up.

## If the table does not exist yet

Say so, and generate it rather than guessing. The minimum useful version is a
JSON file with `deprecated`, `useInstead` and `since` per symbol, surfaced
through whatever the agent already reads — an MCP tool, a docs endpoint, or
the instruction file. Cheap to build, and almost nobody has one.
