Kotlin Multiplatform vs React Native: qual escolher em 2026?
Kotlin Multiplatform (KMP) e React Native (RN) representam abordagens distintas para desenvolvimento cross-platform. Enquanto KMP compartilha logica de negocio mantendo UI nativa, React Native renderiza componentes nativos a partir de JavaScript/TypeScript. Este artigo analisa ambas as opcoes em profundidade para orientar sua decisao tecnica.
Visao geral
| Caracteristica | Kotlin Multiplatform | React Native |
|---|---|---|
| Empresa | JetBrains | Meta (Facebook) |
| Linguagem | Kotlin | JavaScript/TypeScript |
| Arquitetura | Compilacao nativa | Bridge / New Architecture (JSI) |
| Compartilhamento | Logica de negocio | Logica + UI |
| Componentes UI | Nativos (SwiftUI/Compose) | Nativos via bridge |
| Hot reload | Limitado | Fast Refresh |
| Ecossistema web | Separado | Compartilha com React |
| Tipagem | Estatica forte | Dinamica (TS: estatica) |
Arquitetura e funcionamento
Kotlin Multiplatform
KMP compila codigo Kotlin para cada plataforma alvo. No Android, gera bytecode JVM. No iOS, gera codigo nativo ARM via Kotlin/Native. Nao ha runtime intermediario nem bridge de comunicacao. O codigo compartilhado e executado com a mesma performance de codigo nativo porque ele e codigo nativo.
// commonMain - compartilhado entre plataformas
class ProdutoRepositorio(
private val api: ProdutoApi,
private val cache: ProdutoCache
) {
suspend fun buscarProdutos(categoria: String): List<Produto> {
val cacheados = cache.buscar(categoria)
if (cacheados.isNotEmpty()) return cacheados
val produtos = api.listarPorCategoria(categoria)
cache.salvar(categoria, produtos)
return produtos
}
suspend fun buscarDetalhes(id: Long): ProdutoDetalhes {
return api.detalhes(id)
}
}
// commonMain - ViewModel compartilhado
class CatalogoViewModel(
private val repositorio: ProdutoRepositorio
) : ViewModel() {
private val _produtos = MutableStateFlow<List<Produto>>(emptyList())
val produtos: StateFlow<List<Produto>> = _produtos.asStateFlow()
private val _carregando = MutableStateFlow(false)
val carregando: StateFlow<Boolean> = _carregando.asStateFlow()
fun carregar(categoria: String) {
viewModelScope.launch {
_carregando.value = true
try {
_produtos.value = repositorio.buscarProdutos(categoria)
} finally {
_carregando.value = false
}
}
}
}
React Native
React Native executa JavaScript em um motor JS (Hermes) e comunica com componentes nativos. A New Architecture (introduzida no RN 0.74+) usa JSI (JavaScript Interface) para comunicacao sincrona com o lado nativo, eliminando a bridge assincrona antiga:
// React Native com TypeScript
interface Produto {
id: number;
nome: string;
preco: number;
categoria: string;
}
const useProdutos = (categoria: string) => {
const [produtos, setProdutos] = useState<Produto[]>([]);
const [carregando, setCarregando] = useState(false);
const carregar = useCallback(async () => {
setCarregando(true);
try {
const resposta = await fetch(`https://api.exemplo.com/produtos?cat=${categoria}`);
const dados: Produto[] = await resposta.json();
setProdutos(dados);
} catch (erro) {
console.error('Erro ao carregar produtos:', erro);
} finally {
setCarregando(false);
}
}, [categoria]);
useEffect(() => {
carregar();
}, [carregar]);
return { produtos, carregando, recarregar: carregar };
};
const TelaCatalogo: React.FC = () => {
const { produtos, carregando } = useProdutos('eletronicos');
if (carregando) return <ActivityIndicator />;
return (
<FlatList
data={produtos}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => (
<View style={styles.card}>
<Text style={styles.nome}>{item.nome}</Text>
<Text style={styles.preco}>R$ {item.preco.toFixed(2)}</Text>
</View>
)}
/>
);
};
Performance
A performance e uma das maiores diferencas entre as duas abordagens.
| Metrica | KMP | React Native |
|---|---|---|
| Startup (cold) | Nativo | +200-500ms (JS engine) |
| Logica de negocio | Compilada nativa | Interpretada (Hermes) |
| Renderizacao UI | Nativa direta | Nativa via bridge/JSI |
| Animacoes | 60/120fps nativo | Reanimated: 60/120fps |
| Uso de memoria | Nativo | +30-50MB (JS runtime) |
| Operacoes CPU intensivas | Nativo | 2-10x mais lento |
Para operacoes de I/O (rede, banco de dados), a diferenca e minima porque ambos delegam para codigo nativo. Para operacoes CPU intensivas como criptografia, processamento de imagem ou calculos complexos, KMP tem vantagem significativa porque o codigo e compilado nativamente.
React Native com a New Architecture e Hermes melhorou consideravelmente, mas ainda carrega o overhead de um runtime JavaScript.
Compartilhamento de codigo
KMP: logica compartilhada, UI nativa
projeto-kmp/
shared/
commonMain/ --> Logica compartilhada (Kotlin)
androidMain/ --> Implementacoes Android
iosMain/ --> Implementacoes iOS
androidApp/ --> UI Android (Compose)
iosApp/ --> UI iOS (SwiftUI)
O codigo compartilhado tipicamente inclui: modelos de dados, repositorios, view models, validacoes, logica de negocio, networking e acesso a banco. A UI e 100% nativa.
React Native: quase tudo compartilhado
projeto-rn/
src/
components/ --> Componentes UI (React Native)
hooks/ --> Logica compartilhada
services/ --> API e servicos
screens/ --> Telas
android/ --> Codigo nativo Android (minimo)
ios/ --> Codigo nativo iOS (minimo)
React Native compartilha entre 85-95% do codigo, incluindo UI. Codigo nativo especifico e necessario apenas para funcionalidades de plataforma sem modulo RN disponivel.
Seguranca de tipos
Kotlin oferece tipagem estatica forte nativa. TypeScript adiciona tipos a JavaScript, mas a verificacao e em tempo de compilacao apenas e pode ser burlada:
// Kotlin: seguranca de tipos garantida pelo compilador
data class Pedido(
val id: Long,
val valor: Double,
val itens: List<ItemPedido>
)
fun calcularTotal(pedido: Pedido): Double {
return pedido.itens.sumOf { it.preco * it.quantidade }
}
// Impossivel chamar com tipos errados
// TypeScript: tipos podem ser contornados
interface Pedido {
id: number;
valor: number;
itens: ItemPedido[];
}
function calcularTotal(pedido: Pedido): number {
return pedido.itens.reduce((acc, item) => acc + item.preco * item.quantidade, 0);
}
// 'any' pode contornar a tipagem
const resultado = calcularTotal({} as any); // compila mas falha em runtime
Ecossistema e comunidade
React Native
React Native tem uma comunidade enorme e anos de maturidade. O ecossistema npm oferece bibliotecas para quase tudo, e desenvolvedores web com React podem transicionar rapidamente. Empresas como Meta, Microsoft, Shopify e Discord usam React Native em producao.
Kotlin Multiplatform
KMP tem uma comunidade menor mas em crescimento acelerado. Empresas como Netflix, McDonald’s, VMware e Philips adotaram KMP. O ecossistema de bibliotecas KMP e menor que o de RN, mas cobre as necessidades principais e permite acesso a qualquer biblioteca nativa de cada plataforma.
Integracao com equipes existentes
Equipe Android + iOS
Se voce tem desenvolvedores Android (Kotlin) e iOS (Swift) separados, KMP permite que a equipe Android escreva o codigo compartilhado e a equipe iOS continue usando Swift para a UI. A transicao e gradual e nao requer que ninguem aprenda uma nova linguagem para sua plataforma.
Equipe web (React)
Se voce tem desenvolvedores React web, React Native e a escolha natural. Eles ja conhecem React, JSX, hooks e o ecossistema npm. A transicao para mobile e suave, e muitos conceitos sao transferiveis.
Quando usar cada um
Escolha Kotlin Multiplatform quando:
- Performance nativa e requisito critico
- A equipe ja tem desenvolvedores Android com Kotlin
- Voce quer UI que siga perfeitamente as guidelines de cada plataforma
- O app precisa de operacoes CPU intensivas
- Seguranca de tipos forte e prioridade
- Voce quer adotar compartilhamento incrementalmente
Escolha React Native quando:
- A equipe vem do ecossistema web/React
- Velocidade de desenvolvimento e prioridade sobre performance pura
- O app e predominantemente baseado em telas de formularios e listagens
- Voce quer maximizar o compartilhamento de codigo (incluindo UI)
- Fast Refresh para iteracao rapida e importante
- Voce tambem precisa de uma versao web (React Native Web)
Veredito
Em 2026, ambas as tecnologias sao opcoes solidas para desenvolvimento cross-platform. KMP e superior quando performance nativa, seguranca de tipos e experiencia de plataforma sao prioridades. React Native e superior quando velocidade de desenvolvimento, maximizacao de compartilhamento de codigo e aproveitamento de conhecimento web sao mais importantes.
A escolha ideal depende da composicao da sua equipe e das prioridades do projeto. Se sua equipe e forte em Kotlin/Swift e voce quer a melhor experiencia nativa possivel, KMP e o caminho. Se sua equipe e forte em JavaScript/TypeScript e voce quer entregar rapido com maximo compartilhamento, React Native e a resposta. Nenhuma escolha e errada – ambas resolvem o problema de cross-platform de formas diferentes e complementares.