deprecation-and-migration
addyosmani/agent-skills
Orientar o processo de descontinuação de sistemas, APIs ou recursos antigos e a migração dos usuários para as alternativas, incluindo estruturas de decisão, padrões de migração e estratégias de remoção.
...Expandir tudoDescontinuação e migração
Visão geral
O código é um passivo, não um ativo. Cada linha de código acarreta custos contínuos de manutenção — bugs a serem corrigidos, dependências a serem atualizadas, patches de segurança a serem aplicados e novos engenheiros a serem integrados. A descontinuação é a disciplina de remover código que não traz mais retorno, e a migração é o processo de transferir os usuários com segurança do sistema antigo para o novo.
A maioria das equipes de engenharia é boa em criar coisas. Poucas são boas em removê-las. Essa habilidade preenche essa lacuna.
Quando usar
- Substituir um sistema, API ou biblioteca antiga por uma nova
- Desativar um recurso que não é mais necessário
- Consolidar implementações duplicadas
- Remover código obsoleto do qual ninguém é responsável, mas do qual todos dependem
- Planejamento do ciclo de vida de um novo sistema (o planejamento de descontinuação começa na fase de projeto)
- Decidir se deve-se manter um sistema legado ou investir na migração
Princípios fundamentais
Código é um passivo
Cada linha de código tem um custo contínuo: ela precisa de testes, documentação, patches de segurança, atualizações de dependências e esforço mental de quem trabalha com ela. O valor do código está na funcionalidade que ele oferece, não no código em si. Quando a mesma funcionalidade pode ser oferecida com menos código, menos complexidade ou melhores abstrações — o código antigo deve ser descartado.
A Lei de Hyrum dificulta a remoção
Com um número suficiente de usuários, todo comportamento observável passa a ser algo do qual se depende — incluindo bugs, peculiaridades de tempo e efeitos colaterais não documentados. É por isso que a descontinuação requer uma migração ativa, não apenas um anúncio. Os usuários não podem “simplesmente mudar” quando dependem de comportamentos que o substituto não reproduz.
O planejamento da obsolescência começa na fase de projeto
Ao criar algo novo, pergunte-se: “Como removeríamos isso daqui a 3 anos?” Sistemas projetados com interfaces limpas, sinalizadores de recursos e área de exposição mínima são mais fáceis de descontinuar do que sistemas que expõem detalhes de implementação por toda parte.
A decisão de descontinuar
Antes de descontinuar qualquer coisa, responda a estas perguntas:
1. Este sistema ainda oferece valor único?
→ Se sim, mantenha-o. Se não, prossiga.
2. Quantos usuários/consumidores dependem dele?
→ Quantifique o escopo da migração.
3. Existe um substituto?
→ Se não, desenvolva o substituto primeiro. Não descontinue sem uma alternativa.
4. Qual é o custo da migração para cada consumidor?
→ Se for trivialmente automatizado, faça-o. Se for manual e exigir muito esforço, avalie em relação ao custo de manutenção.
5. Qual é o custo de manutenção contínua de NÃO descontinuar?
→ Risco de segurança, tempo dos engenheiros, custo de oportunidade da complexidade.
Descontinuação obrigatória x recomendada
| Tipo | Quando usar | Mecanismo |
|---|---|---|
| Recomendada | A migração é opcional, o sistema antigo está estável | Avisos, documentação, lembretes. Os usuários migram no seu próprio ritmo. |
| Obrigatória | O sistema antigo apresenta problemas de segurança, impede o progresso ou o custo de manutenção é insustentável | Prazo rígido. O sistema antigo será removido até a data X. Forneça ferramentas de migração. |
Por padrão, opte pela recomendação. Use a obrigatoriedade apenas quando o custo de manutenção ou o risco justificarem forçar a migração. A descontinuação obrigatória exige o fornecimento de ferramentas de migração, documentação e suporte — não basta apenas anunciar um prazo.
O processo de migração
Etapa 1: Desenvolver a Substituição
Não descontinue o uso sem uma alternativa funcional. O substituto deve:
- Abranger todos os casos de uso críticos do sistema antigo
- Ter documentação e guias de migração
- Ter sido comprovada em produção (não apenas ser “teoricamente melhor”)
Passo 2: Anunciar e documentar
## Aviso de descontinuação: OldService
**Status:** Descontinuado a partir de 01/03/2025
**Substituto:** NewService (consulte o guia de migração abaixo)
**Data de remoção:** Recomendação — ainda não há prazo definido
**Motivo:** O OldService requer dimensionamento manual e carece de observabilidade.
O NewService lida com ambos automaticamente.
### Guia de migração
1. Substitua `import { client } from 'old-service'` por `import { client } from 'new-service'`
2. Atualize a configuração (veja os exemplos abaixo)
3. Execute o script de verificação da migração: `npx migrate-check`
Etapa 3: Migre de forma incremental
Migre os consumidores um por um, não todos de uma vez. Para cada consumidor:
1. Identifique todos os pontos de contato com o sistema obsoleto
2. Atualize para usar o substituto
3. Verifique se o comportamento está correto (testes, verificações de integração)
4. Remova as referências ao sistema antigo
5. Confirme que não há regressões
A regra do Churn: se você é responsável pela infraestrutura que está sendo descontinuada, cabe a você migrar seus usuários — ou fornecer atualizações compatíveis com versões anteriores que não exijam migração. Não anuncie a descontinuação e deixe que os usuários descubram sozinhos.
Etapa 4: Remova o sistema antigo
Somente depois que todos os usuários tiverem migrado:
1. Verifique se não há nenhum uso ativo (métricas, logs, análise de dependências)
2. Remova o código
3. Remova os testes, a documentação e a configuração associados
4. Remova os avisos de descontinuação
5. Comemore — remover código é uma conquista
Padrões de migração
Padrão Strangler
Execute os sistemas antigo e novo em paralelo. Redirecione o tráfego de forma incremental do antigo para o novo. Quando o sistema antigo estiver processando 0% do tráfego, remova-o.
Fase 1: O novo sistema processa 0%, o antigo processa 100%
Fase 2: O novo sistema processa 10% (canário)
Fase 3: O novo sistema processa 50%
Fase 4: O novo sistema processa 100%, o sistema antigo fica ocioso
Fase 5: Remova o sistema antigo
Padrão Adaptador
Crie um adaptador que traduza as chamadas da interface antiga para a nova implementação. Os usuários continuam usando a interface antiga enquanto você migra o back-end.
// Adaptador: interface antiga, nova implementação
class LegacyTaskService implements OldTaskAPI {
constructor(private newService: NewTaskService) {}
// Assinatura do método antigo, delega para a nova implementação
getTask(id: number): OldTask {
const task = this.newService.findById(String(id));
return this.toOldFormat(task);
}
}
Migração por sinalizadores de recurso
Use sinalizadores de recurso para migrar os consumidores do sistema antigo para o novo, um por um:
função getTaskService(userId: string): TaskService {
if (featureFlags.isEnabled('new-task-service', { userId })) {
return new NewTaskService();
}
return new LegacyTaskService();
}
Código “zumbi”
Código “zumbi” é aquele que ninguém é responsável, mas do qual todos dependem. Ele não recebe manutenção ativa, não tem um responsável claro e acumula vulnerabilidades de segurança e problemas de compatibilidade. Sinais:
- Não há commits há mais de 6 meses, mas existem usuários ativos
- Não há mantenedor ou equipe designada
- Testes com falhas que ninguém corrige
- Dependências com vulnerabilidades conhecidas que ninguém atualiza
- Documentação que faz referência a sistemas que não existem mais
Resposta: Ou se designa um responsável e se mantém o projeto adequadamente, ou se o torna obsoleto com um plano de migração concreto. Código “zumbi” não pode ficar no limbo — ele precisa receber investimento ou ser removido.
Racionalizações comuns
| Racionalização | Realidade |
|---|---|
| “Ainda funciona, por que removê-lo?” | Código funcional que ninguém mantém acumula dívida de segurança e complexidade. O custo de manutenção cresce silenciosamente. |
| “Alguém pode precisar disso mais tarde” | Se for necessário mais tarde, pode ser reconstruído. Manter código não utilizado “por precaução” custa mais do que reconstruí-lo. |
| “A migração é muito cara” | Compare o custo da migração com o custo de manutenção contínua ao longo de 2 a 3 anos. A migração costuma ser mais barata no longo prazo. |
| “Vamos descontinuá-lo depois que terminarmos o novo sistema” | O planejamento da descontinuação começa já na fase de projeto. Quando o novo sistema estiver pronto, você terá novas prioridades. Planeje agora. |
| “Os usuários vão migrar por conta própria” | Eles não vão. Forneça ferramentas, documentação e incentivos — ou faça a migração você mesmo (a Regra da Rotatividade). |
| “Podemos manter os dois sistemas indefinidamente” | Dois sistemas fazendo a mesma coisa significam o dobro dos custos de manutenção, testes, documentação e integração. |
Sinais de alerta
- Sistemas obsoletos sem substituto disponível
- Anúncios de descontinuação sem ferramentas de migração ou documentação
- Descontinuação “suave” que vem sendo recomendada há anos, sem nenhum progresso
- Código “zumbi” sem responsável e com usuários ativos
- Novos recursos adicionados a um sistema obsoleto (invista no substituto, em vez disso)
- Descontinuação sem avaliar o uso atual
- Remoção de código sem verificar se há zero usuários ativos
Verificação
Após concluir uma descontinuação:
- A substituição foi comprovada em produção e abrange todos os casos de uso críticos
- Existe um guia de migração com etapas concretas e exemplos
- Todos os consumidores ativos foram migrados (verificado por métricas/logs)
- O código antigo, os testes, a documentação e a configuração foram totalmente removidos
- Não há mais referências ao sistema obsoleto na base de código
- Os avisos de descontinuação foram removidos (eles cumpriram seu propósito)
---
name: deprecation-and-migration
description: Guides the process of deprecating old systems, APIs, or features and migrating users to replacements, including decision frameworks, migration patterns, and removal strategies.
---
# Deprecation and Migration
## Overview
Code is a liability, not an asset. Every line of code has ongoing maintenance cost — bugs to fix, dependencies to update, security patches to apply, and new engineers to onboard. Deprecation is the discipline of removing code that no longer earns its keep, and migration is the process of moving users safely from the old to the new.
Most engineering organizations are good at building things. Few are good at removing them. This skill addresses that gap.
## When to Use
- Replacing an old system, API, or library with a new one
- Sunsetting a feature that's no longer needed
- Consolidating duplicate implementations
- Removing dead code that nobody owns but everybody depends on
- Planning the lifecycle of a new system (deprecation planning starts at design time)
- Deciding whether to maintain a legacy system or invest in migration
## Core Principles
### Code Is a Liability
Every line of code has ongoing cost: it needs tests, documentation, security patches, dependency updates, and mental overhead for anyone working nearby. The value of code is the functionality it provides, not the code itself. When the same functionality can be provided with less code, less complexity, or better abstractions — the old code should go.
### Hyrum's Law Makes Removal Hard
With enough users, every observable behavior becomes depended on — including bugs, timing quirks, and undocumented side effects. This is why deprecation requires active migration, not just announcement. Users can't "just switch" when they depend on behaviors the replacement doesn't replicate.
### Deprecation Planning Starts at Design Time
When building something new, ask: "How would we remove this in 3 years?" Systems designed with clean interfaces, feature flags, and minimal surface area are easier to deprecate than systems that leak implementation details everywhere.
## The Deprecation Decision
Before deprecating anything, answer these questions:
```
1. Does this system still provide unique value?
→ If yes, maintain it. If no, proceed.
2. How many users/consumers depend on it?
→ Quantify the migration scope.
3. Does a replacement exist?
→ If no, build the replacement first. Don't deprecate without an alternative.
4. What's the migration cost for each consumer?
→ If trivially automated, do it. If manual and high-effort, weigh against maintenance cost.
5. What's the ongoing maintenance cost of NOT deprecating?
→ Security risk, engineer time, opportunity cost of complexity.
```
## Compulsory vs Advisory Deprecation
| Type | When to Use | Mechanism |
|------|-------------|-----------|
| **Advisory** | Migration is optional, old system is stable | Warnings, documentation, nudges. Users migrate on their own timeline. |
| **Compulsory** | Old system has security issues, blocks progress, or maintenance cost is unsustainable | Hard deadline. Old system will be removed by date X. Provide migration tooling. |
**Default to advisory.** Use compulsory only when the maintenance cost or risk justifies forcing migration. Compulsory deprecation requires providing migration tooling, documentation, and support — you can't just announce a deadline.
## The Migration Process
### Step 1: Build the Replacement
Don't deprecate without a working alternative. The replacement must:
- Cover all critical use cases of the old system
- Have documentation and migration guides
- Be proven in production (not just "theoretically better")
### Step 2: Announce and Document
```markdown
## Deprecation Notice: OldService
**Status:** Deprecated as of 2025-03-01
**Replacement:** NewService (see migration guide below)
**Removal date:** Advisory — no hard deadline yet
**Reason:** OldService requires manual scaling and lacks observability.
NewService handles both automatically.
### Migration Guide
1. Replace `import { client } from 'old-service'` with `import { client } from 'new-service'`
2. Update configuration (see examples below)
3. Run the migration verification script: `npx migrate-check`
```
### Step 3: Migrate Incrementally
Migrate consumers one at a time, not all at once. For each consumer:
```
1. Identify all touchpoints with the deprecated system
2. Update to use the replacement
3. Verify behavior matches (tests, integration checks)
4. Remove references to the old system
5. Confirm no regressions
```
**The Churn Rule:** If you own the infrastructure being deprecated, you are responsible for migrating your users — or providing backward-compatible updates that require no migration. Don't announce deprecation and leave users to figure it out.
### Step 4: Remove the Old System
Only after all consumers have migrated:
```
1. Verify zero active usage (metrics, logs, dependency analysis)
2. Remove the code
3. Remove associated tests, documentation, and configuration
4. Remove the deprecation notices
5. Celebrate — removing code is an achievement
```
## Migration Patterns
### Strangler Pattern
Run old and new systems in parallel. Route traffic incrementally from old to new. When the old system handles 0% of traffic, remove it.
```
Phase 1: New system handles 0%, old handles 100%
Phase 2: New system handles 10% (canary)
Phase 3: New system handles 50%
Phase 4: New system handles 100%, old system idle
Phase 5: Remove old system
```
### Adapter Pattern
Create an adapter that translates calls from the old interface to the new implementation. Consumers keep using the old interface while you migrate the backend.
```typescript
// Adapter: old interface, new implementation
class LegacyTaskService implements OldTaskAPI {
constructor(private newService: NewTaskService) {}
// Old method signature, delegates to new implementation
getTask(id: number): OldTask {
const task = this.newService.findById(String(id));
return this.toOldFormat(task);
}
}
```
### Feature Flag Migration
Use feature flags to switch consumers from old to new system one at a time:
```typescript
function getTaskService(userId: string): TaskService {
if (featureFlags.isEnabled('new-task-service', { userId })) {
return new NewTaskService();
}
return new LegacyTaskService();
}
```
## Zombie Code
Zombie code is code that nobody owns but everybody depends on. It's not actively maintained, has no clear owner, and accumulates security vulnerabilities and compatibility issues. Signs:
- No commits in 6+ months but active consumers exist
- No assigned maintainer or team
- Failing tests that nobody fixes
- Dependencies with known vulnerabilities that nobody updates
- Documentation that references systems that no longer exist
**Response:** Either assign an owner and maintain it properly, or deprecate it with a concrete migration plan. Zombie code cannot stay in limbo — it either gets investment or removal.
## Common Rationalizations
| Rationalization | Reality |
|---|---|
| "It still works, why remove it?" | Working code that nobody maintains accumulates security debt and complexity. Maintenance cost grows silently. |
| "Someone might need it later" | If it's needed later, it can be rebuilt. Keeping unused code "just in case" costs more than rebuilding. |
| "The migration is too expensive" | Compare migration cost to ongoing maintenance cost over 2-3 years. Migration is usually cheaper long-term. |
| "We'll deprecate it after we finish the new system" | Deprecation planning starts at design time. By the time the new system is done, you'll have new priorities. Plan now. |
| "Users will migrate on their own" | They won't. Provide tooling, documentation, and incentives — or do the migration yourself (the Churn Rule). |
| "We can maintain both systems indefinitely" | Two systems doing the same thing is double the maintenance, testing, documentation, and onboarding cost. |
## Red Flags
- Deprecated systems with no replacement available
- Deprecation announcements with no migration tooling or documentation
- "Soft" deprecation that's been advisory for years with no progress
- Zombie code with no owner and active consumers
- New features added to a deprecated system (invest in the replacement instead)
- Deprecation without measuring current usage
- Removing code without verifying zero active consumers
## Verification
After completing a deprecation:
- [ ] Replacement is production-proven and covers all critical use cases
- [ ] Migration guide exists with concrete steps and examples
- [ ] All active consumers have been migrated (verified by metrics/logs)
- [ ] Old code, tests, documentation, and configuration are fully removed
- [ ] No references to the deprecated system remain in the codebase
- [ ] Deprecation notices are removed (they served their purpose)
Todos os arquivos
0 arquivosInstalar deprecation-and-migration
Baixe e extraia os arquivos de habilidades para o diretório .claude/skills/.
Baixar ZIPClone o repositório e copie os arquivos da habilidade para o seu projeto.
git clone https://github.com/addyosmani/agent-skills/tree/main/skills/deprecation-and-migration # Copy SKILL.md to your .claude/skills/ directory
Copiar





Lar
