Vale a pena migrar de React Native para Kotlin e Swift agora que temos IA?
Veja quando migrar de React Native para Kotlin e Swift com ajuda de IA faz sentido, quais custos permanecem e como testar a decisão com menos risco.
A IA pode baratear a tradução do código, mas não necessariamente barateia a operação de duas plataformas.
Durante muito tempo, uma reescrita mobile completa parecia uma decisão reservada para equipes com bastante tempo, orçamento e conhecimento nativo. Converter telas, estados, navegação, integrações e testes para Android e iOS exigia um esforço grande antes mesmo de o produto perceber algum benefício.
Agentes de código mudaram parte dessa equação. Hoje eles conseguem inventariar uma base React Native, mapear dependências e gerar primeiras versões em Kotlin, Swift, Jetpack Compose e SwiftUI muito mais rápido. Isso torna uma demonstração acessível, mas também cria o risco de confundir uma tela renderizando com uma migração concluída.
A resposta curta: depende do problema que a migração resolve
Eu não migraria de React Native para Kotlin e Swift apenas porque a geração de código ficou mais rápida. Consideraria a mudança quando existisse um problema relevante e medido que continuasse presente depois de avaliar alternativas menores: atualizar a base, revisar bibliotecas, melhorar a arquitetura interna, escrever um módulo nativo ou substituir somente um fluxo crítico.
- Qual problema concreto queremos resolver?
- Como vamos demonstrar que a versão nova é melhor?
- Quem revisará e manterá Kotlin e Swift no próximo ano?
- Quanto custará o período em que as implementações coexistirem?
- Qual é o caminho de volta se o piloto não confirmar a hipótese?
Sem respostas minimamente claras, a disponibilidade de IA é um argumento para experimentar, não para migrar.
O que a IA realmente muda
A IA reduz principalmente o custo marginal de produzir e analisar código. Ela pode inventariar telas, explicar áreas pouco conhecidas, gerar scaffolding, traduzir modelos simples, sugerir testes, comparar implementações e documentar decisões. Esse ganho pode transformar uma hipótese cara em um protótipo viável.
Mas ela não define sozinha qual comportamento está correto. Não conhece automaticamente todas as decisões de produto que ficaram implícitas ao longo dos anos e não assume responsabilidade por ciclo de vida, consumo de bateria, concorrência, permissões, acessibilidade, publicação nas lojas ou falhas específicas de dispositivos.
Também existe uma diferença entre gerar testes e possuir uma especificação independente. Se um agente interpreta uma regra incorretamente, ele pode escrever implementação e teste com o mesmo erro. O relatório da DORA sobre IA generativa reforça a cautela: melhorar partes do processo não melhora automaticamente o desempenho de entrega; lotes pequenos e testes robustos continuam importantes.
Migração mobile não é tradução de componentes
- Navegação, deep links e restauração de estado.
- Autenticação, armazenamento seguro e comportamento offline.
- Notificações, tarefas em background, analytics e crash reporting.
- Câmera, localização, Bluetooth, permissões e diferenças entre versões.
- Acessibilidade, internacionalização, assinatura e publicação.
- Contratos com APIs, persistência local e ciclos de pouca memória.
Uma tradução sintaticamente elegante pode remover justamente a exceção que mantinha o produto funcionando. Antes de converter arquivos, eu registraria comportamentos e contratos: quais resultados precisam continuar verdadeiros e quais limitações a migração pretende remover.
Antes de abandonar React Native, revise a hipótese
React Native não é uma peça estática. A New Architecture alterou módulos nativos, renderização e comunicação com a plataforma. A documentação oficial também prevê código específico por plataforma, módulos nativos e convivência entre superfícies React Native e aplicações nativas. Isso não garante que atualizar resolverá tudo; significa que diagnósticos como `React Native é lento` ou `precisamos de recursos nativos` são amplos demais para justificar uma reescrita.
- O gargalo está no framework, no código da aplicação ou em uma biblioteca?
- A base usa uma versão e uma arquitetura atuais?
- O problema acontece nas duas plataformas e foi medido em dispositivos reais?
- Um componente ou módulo nativo resolveria a parte crítica?
- O custo das atualizações é estrutural ou consequência de dependências específicas?
Quatro caminhos, não apenas dois
1. Manter e evoluir React Native
Faz sentido quando o aplicativo entrega a experiência esperada, o compartilhamento reduz custo real e os problemas podem ser resolvidos na base atual. Isso pode incluir atualização, adoção gradual da New Architecture, revisão de dependências, melhor observabilidade e separação de domínios.
2. Adicionar módulos, componentes ou fluxos nativos
Quando o problema está concentrado em câmera, mapas, mídia, background, sensores ou animação, uma solução nativa delimitada pode entregar o benefício sem duplicar o aplicativo inteiro. O custo é manter uma fronteira clara entre ambientes e conhecimento dos dois lados.
3. Migrar gradualmente por fluxo
A equipe escolhe uma jornada delimitada e a reimplementa de ponta a ponta em Kotlin e Swift, com testes, telemetria, rollout e rollback próprios. O resultado decide se a migração continua, muda de direção ou para. É a alternativa mais próxima do padrão Strangler Fig.
4. Fazer uma reescrita completa
Pode ser adequada quando os limites são sistêmicos, a arquitetura atual impede mudanças importantes e a organização aceita o investimento e o risco de um corte amplo. A IA reduz parte da implementação, mas não remove a distância entre `quase tudo pronto` e `seguro para substituir produção`.
Quando migrar pode fazer sentido
- Existe um gargalo relevante, reproduzível e medido.
- O problema permanece depois de melhorias razoáveis na base React Native.
- O produto depende profundamente de APIs ou comportamentos específicos de cada plataforma.
- A camada compartilhada exige exceções suficientes para deixar de simplificar o trabalho.
- A equipe possui conhecimento nativo ou um plano sustentável para desenvolvê-lo.
- Existem testes, telemetria, rollout e rollback para comparar versões.
- A organização aceita o custo de convivência e a redução temporária de velocidade.
Quando provavelmente não faz sentido
- A motivação principal é a novidade de um agente ou linguagem.
- Uma demonstração rápida foi tratada como estimativa de produção.
- Não existe linha de base do aplicativo atual.
- A equipe não consegue revisar Kotlin e Swift com profundidade.
- Os testes não conseguem dizer se a conversão preservou comportamento.
- A paridade precisa ser completa, mas não há capacidade para manter implementações sincronizadas.
- O custo depois do lançamento não foi discutido.
Se ninguém consegue explicar por que o código gerado está correto, a velocidade de produção vira dívida técnica em duas linguagens.
O custo total aparece em três momentos
1. Construção
Mapear a aplicação, definir arquiteturas, gerar e revisar código, recriar testes, instrumentar observabilidade, documentar decisões e capacitar pessoas. É onde a IA tende a produzir o ganho mais visível.
2. Transição
Manter React Native enquanto as versões nativas amadurecem, corrigir problemas em mais de um lugar, sincronizar funcionalidades, duplicar temporariamente pipelines e telemetria, migrar deep links e autenticação e reduzir capacidade para novas funcionalidades.
3. Operação recorrente
Duas toolchains, dois ecossistemas de dependências, builds e releases separados, revisão especializada, mudanças das lojas, segurança, observabilidade, compatibilidade, onboarding e coordenação de paridade ou divergência intencional.
1custo total = construção + transição + operação recorrente + oportunidade + risco residualParidade, testes e arquitetura de equipe
Paridade não precisa significar copiar cada pixel. Eu separaria comportamento comum obrigatório, experiência deliberadamente específica por plataforma e diferenças temporárias da migração. Isso evita reproduzir detalhes irrelevantes e também impede que regressões sejam chamadas de escolhas nativas.
Em `Working Effectively with Legacy Code`, Michael Feathers mostra a importância de criar segurança antes de mudar agressivamente uma base. Para uma migração mobile, isso inclui testes de caracterização, contratos de API, fluxos críticos, acessibilidade, desempenho e cenários de rede ruim, suspensão e pouca memória. Essa cobertura deve começar antes da conversão.
`Team Topologies`, de Matthew Skelton e Manuel Pais, ajuda a incluir carga cognitiva na decisão. A IA pode reduzir trabalho mecânico, mas também aumentar a carga de revisão se gerar mais mudanças do que a equipe consegue compreender. Duas plataformas pedem ownership, conhecimento distribuído e capacidade para responder a incidentes em ambos os ecossistemas.
O piloto que eu faria antes de migrar
Imagine um aplicativo com um fluxo de captura, edição e envio de mídia que apresenta falhas reproduzíveis, uso elevado de memória e diferenças difíceis de tratar entre Android e iOS. Eu escolheria esse fluxo porque ele contém o problema que motivou a discussão, não porque é a parte mais fácil de demonstrar.
- Medir a versão atual: conclusão, crashes, tempo, memória, retomada, acessibilidade e custo de manutenção.
- Testar a menor alternativa: atualização, biblioteca melhor ou módulo nativo.
- Criar implementações nativas delimitadas, com contratos e revisão de especialistas.
- Liberar com controle, telemetria comparável e rollback já testado.
- Decidir com evidência se deve permanecer, manter o módulo, continuar por fluxos ou ampliar a migração.
Um piloto que recomenda não migrar não foi desperdício. Ele comprou conhecimento e evitou uma aposta maior.
O que os livros ajudam a enxergar
- `Building Evolutionary Architectures`: mudanças incrementais e fitness functions tornam características importantes verificáveis durante a evolução.
- `Working Effectively with Legacy Code`: testes de caracterização e seams criam segurança para mudar uma base pouco conhecida.
- `Software Architecture: The Hard Parts`: não existe vencedor fora do contexto; benefícios de uma alternativa costumam ser os custos da outra.
- `Accelerate` e DORA: produtividade local não basta se mudanças maiores aumentam revisão, instabilidade e tempo de recuperação.
- `Team Topologies`: a arquitetura precisa caber na capacidade cognitiva e nos limites de responsabilidade da equipe.
- `Strangler Fig`: substituir capacidades gradualmente reduz o risco de um corte único.
Checklist antes de decidir
- Qual problema de produto, arquitetura ou operação queremos resolver?
- Existe uma linha de base reproduzível?
- O problema está no React Native, na aplicação ou em uma dependência?
- Atualização, otimização ou módulo nativo foram avaliados?
- Quais comportamentos precisam permanecer equivalentes?
- Quais diferenças entre Android e iOS serão intencionais?
- A equipe consegue revisar e manter Kotlin e Swift?
- Quanto custará o período de convivência?
- Quais métricas definem sucesso e interrupção?
- O piloto pode ser liberado e revertido com segurança?
- Como a IA será usada em lotes pequenos e revisáveis?
- Quem ficará responsável pelo código depois da geração?
Conclusão
A IA tornou mais barato perguntar `e se migrássemos?`. Ela ajuda a mapear a base, criar protótipos e executar partes mecânicas da transição. Mas um produto não termina quando o código é gerado: ele precisa ser revisado, testado, publicado, observado, corrigido e evoluído.
Por isso, eu não usaria IA como justificativa para uma reescrita. Usaria IA para tornar a decisão mais barata de testar. Se um fluxo pequeno, medido e reversível demonstrar benefício suficiente, a migração pode avançar com evidência. Se não demonstrar, permanecer no React Native — talvez com integrações nativas pontuais — continua sendo uma decisão técnica válida.
A pergunta não é se a IA consegue escrever Kotlin e Swift. É se a nova arquitetura resolve um problema importante por um custo que a equipe consegue sustentar.
