Mobile em produção: React Native sem romantismo

Publicado em

React Native é uma boa escolha para muitos produtos mobile quando o objetivo é reduzir duplicação de tela, acelerar ciclos de entrega e manter uma base comum entre iOS e Android. Ele deixa de ser vantagem quando o app depende fortemente de APIs nativas, processamento em tempo real, UX muito específica de plataforma ou quando a equipe trata o nativo como detalhe secundário.

A pergunta central não deveria ser se React Native é “melhor” que Swift, Kotlin ou desenvolvimento nativo. A pergunta prática é: qual parte do produto precisa ser compartilhada, qual parte precisa ser nativa e quanto custo operacional a equipe consegue sustentar depois da versão 1.0?

O que muda quando o app sai do protótipo?

No protótipo, React Native costuma brilhar. Uma tela de login, uma lista paginada, um formulário e uma área de configurações podem ser feitos rapidamente com TypeScript, React, navegação declarativa e chamadas HTTP comuns. Em um app real, porém, a complexidade aparece em lugares menos visíveis: inicialização fria, permissões, deep links, notificações, cache offline, crash reporting, analytics, builds assinados e atualização de bibliotecas nativas.

Uma boa regra de engenharia é separar o app em três camadas:

  • Produto compartilhado: fluxos, telas, validações, estados de UI, textos, regras simples e integração com APIs.
  • Infra mobile: navegação, cache, autenticação, telemetria, feature flags, tratamento de erro e atualização remota quando aplicável.
  • Superfície nativa: câmera, biometria, Bluetooth, widgets, intents, background tasks, pagamentos, mapas avançados e integrações específicas.

Quando essa separação é explícita, React Native deixa de ser uma aposta genérica e vira uma decisão arquitetural. O time sabe onde pode ir rápido e onde precisa respeitar as regras de cada plataforma.

Desenvolvedor analisando código de aplicativo mobile em uma tela
Desenvolvedor analisando código de aplicativo mobile em uma tela

Quando React Native funciona melhor?

React Native tende a funcionar muito bem em apps orientados a produto, conteúdo, marketplace, fintech leve, CRM, educação, comunidades, delivery, dashboards internos e ferramentas com muitas telas de negócio. Nesses casos, a maior parte do esforço está em interface, estado, formulários, consumo de API e consistência visual. Compartilhar 60% a 85% do código de aplicação pode ser realista, desde que o time não force o compartilhamento de tudo.

Um padrão simples para apps de negócio é tratar dados remotos como cache controlado, não como estado solto espalhado por componentes. Exemplo:

import { useQuery } from '@tanstack/react-query';

async function getOrders() {
  const response = await fetch('https://api.exemplo.com/orders');
  if (!response.ok) throw new Error('Falha ao carregar pedidos');
  return response.json();
}

export function useOrders() {
  return useQuery({
    queryKey: ['orders'],
    queryFn: getOrders,
    staleTime: 60_000,
    retry: 2
  });
}

Esse tipo de decisão parece pequena, mas evita uma classe inteira de bugs: tela que mostra dado antigo sem querer, loading duplicado, retry manual inconsistente e erro tratado de formas diferentes em cada componente. Em mobile, onde rede oscila, o usuário alterna apps e o sistema pode matar processos em segundo plano, previsibilidade vale muito.

Onde o nativo ainda manda?

Desenvolvimento nativo continua sendo a opção mais forte quando o app depende do comportamento íntimo do sistema operacional. Swift e SwiftUI no iOS, Kotlin e Jetpack Compose no Android dão acesso direto ao ciclo de vida, APIs novas no primeiro dia, ferramentas oficiais de performance e padrões visuais específicos de cada ecossistema.

Isso pesa em apps com câmera avançada, edição de vídeo, áudio em baixa latência, AR, integração profunda com wearables, BLE constante, criptografia com hardware, processamento pesado no dispositivo ou experiência crítica em background. Um app de banco com biometria e push não exige necessariamente nativo puro. Um app de gravação multitrack, navegação offline pesada ou monitoramento médico em tempo real provavelmente exige muito mais cautela.

Também existe o custo de dependências. Em React Native, uma biblioteca npm pode carregar código Objective-C, Swift, Java, Kotlin, configuração de Gradle, pods do CocoaPods e permissões de sistema. Quando ela quebra em uma atualização do Xcode, do Android Gradle Plugin ou do SDK mínimo, o problema deixa de ser JavaScript. A equipe precisa ter alguém capaz de abrir o Xcode, ler logs do Gradle e corrigir integração nativa sem transformar cada incidente em bloqueio.

Por isso, a decisão mais madura muitas vezes não é “React Native contra nativo”, mas “React Native com ilhas nativas bem desenhadas”. Uma tela inteira pode ser nativa. Um módulo crítico pode ser nativo. Um fluxo de pagamento pode usar SDK oficial com bridge mínima. O erro é tentar esconder complexidade nativa atrás de uma abstração frágil só para manter uma narrativa de código único.

Como decidir a arquitetura antes do primeiro sprint?

Antes de abrir o repositório, vale responder perguntas objetivas. O app precisa funcionar offline por horas ou apenas tolerar perda temporária de rede? Vai usar push, biometria, câmera, mapas, pagamentos, widgets ou background sync? A equipe domina TypeScript, mas também consegue debugar Swift e Kotlin? O produto terá releases semanais, quinzenais ou alinhados a ciclos de loja?

Uma matriz simples ajuda:

  • Escolha React Native quando a maior parte do valor está em telas de negócio, velocidade de entrega, consistência entre plataformas e time web forte.
  • Escolha nativo quando performance, APIs recém-lançadas, experiência específica de plataforma ou integração profunda são o centro do produto.
  • Escolha híbrido com módulos nativos quando 80% do app é produto comum, mas 20% concentra requisitos sensíveis.
  • Evite decidir só por custo inicial, porque manutenção, builds, QA e incidentes costumam pesar mais depois do lançamento.

Para o blog, o resumo prático é este: React Native é uma ferramenta forte quando usada com disciplina de engenharia mobile. Ele não substitui arquitetura, observabilidade, testes em dispositivos reais e conhecimento nativo. O melhor app não é o que maximiza código compartilhado, mas o que entrega experiência consistente com um custo de evolução que o time consegue bancar.

Perguntas frequentes

React Native serve para app grande?

Sim, React Native pode servir para app grande quando há arquitetura clara, monitoramento, testes e capacidade de manter integrações nativas. O tamanho do app não é o problema principal; o risco está em dependências mal escolhidas e falta de domínio das plataformas.

React Native é mais barato que app nativo?

Pode ser mais barato no início por compartilhar telas e lógica entre iOS e Android. Mas o custo real depende de QA, integrações nativas, manutenção de builds, performance e complexidade do produto depois do lançamento.

Quando devo escolher Swift e Kotlin em vez de React Native?

Escolha Swift e Kotlin quando o app depende muito de APIs específicas, performance sensível, background processing, câmera avançada, áudio, vídeo, Bluetooth ou UX profundamente diferente entre iOS e Android.

Expo é bom para produção?

Sim, Expo pode ser usado em produção, especialmente com EAS Build e módulos modernos. A decisão deve considerar requisitos nativos, dependências, políticas de atualização e o nível de controle que o app precisa sobre cada plataforma.