A Nova Arquitetura do React Native: Fabric, TurboModules e Bridgeless Mode

Como JSI, Fabric e TurboModules substituem a bridge assíncrona clássica do React Native, e por que o bridgeless mode se tornou padrão a partir da versão 0.76.

Desde o lançamento do React Native, toda comunicação entre o código JavaScript e as camadas nativas (iOS e Android) passava por uma bridge: uma fila assíncrona que serializava mensagens em JSON para os dois lados conversarem. Funcionava, mas tinha um custo real de performance e limitava o que era possível fazer. A Nova Arquitetura substitui essa bridge por três peças — JSI, Fabric e TurboModules — e, a partir do React Native 0.76, passou a vir habilitada por padrão em todo projeto novo.

O problema da bridge antiga

Na arquitetura clássica, uma chamada de um módulo nativo (por exemplo, pedir a localização do GPS) virava uma mensagem serializada, colocada em uma fila, processada de forma assíncrona e só então respondida — tudo isso mesmo quando JavaScript e o código nativo estavam na mesma thread. Isso trazia três limitações conhecidas:

JSI: a base que elimina a bridge

O JSI (JavaScript Interface) é uma camada C++ que dá ao código nativo uma referência direta a objetos JavaScript, permitindo chamar funções nativas como se fossem métodos comuns de um objeto — sem passar por serialização nem pela fila da bridge:

// Com a bridge antiga, uma chamada nativa virava uma Promise
// mesmo quando o resultado já estava disponível em memória
const altura = await NativeModules.DeviceInfo.getScreenHeight();

// Com JSI, o módulo pode expor um valor síncrono de verdade,
// sem o overhead de uma viagem assíncrona pela bridge
const altura = DeviceInfo.getScreenHeightSync();

JSI não é uma API que se usa diretamente no dia a dia — é a fundação sobre a qual Fabric e TurboModules são construídos.

Fabric: o novo renderer

O Fabric é o renderer que substitui o antigo sistema de views. Ele mantém a árvore de elementos (a shadow tree) em C++, compartilhada entre JavaScript e a UI nativa, permitindo que atualizações de layout aconteçam de forma síncrona quando necessário — por exemplo, medir o tamanho real de um componente antes de decidir como renderizar o próximo quadro:

import { useLayoutEffect, useRef, useState } from 'react';
import { View, Text } from 'react-native';

function Tooltip({ texto }) {
    const ref = useRef(null);
    const [altura, setAltura] = useState(0);

    useLayoutEffect(() => {
        // Com Fabric, medir o layout e aplicar o resultado
        // acontece antes do usuário ver qualquer tela intermediária
        ref.current?.measure((x, y, width, height) => {
            setAltura(height);
        });
    }, []);

    return (
        <View ref={ref}>
            <Text>{texto} (altura medida: {altura}px)</Text>
        </View>
    );
}

Esse tipo de medição síncrona era um dos pontos mais frágeis da arquitetura antiga, já que a resposta podia chegar um ou mais quadros depois da renderização.

TurboModules: módulos nativos sob demanda

Os TurboModules substituem os módulos nativos tradicionais. Em vez de registrar e instanciar todos os módulos na inicialização do app, cada módulo só é carregado na primeira vez que o JavaScript realmente o referencia:

import { TurboModuleRegistry } from 'react-native';

// O módulo nativo correspondente só é instanciado
// no momento desta chamada, não no boot do app
const CameraModule = TurboModuleRegistry.getEnforcing('CameraModule');

CameraModule.capturarFoto({ qualidade: 0.8 });

Para quem escreve módulos nativos próprios, isso também significa tipagem forte: a interface do módulo é definida em um arquivo .ts e o Codegen gera o código de ligação em C++ automaticamente, eliminando boa parte dos erros de tipo que antes só apareciam em runtime.

Bridgeless mode

Com Fabric e TurboModules cobrindo renderização e módulos nativos, a bridge original ficou sem função — e pôde ser removida de vez. Esse é o bridgeless mode: a partir do React Native 0.74, ele passou a ser habilitado automaticamente sempre que a Nova Arquitetura está ativa, sem precisar de nenhuma configuração extra no código da aplicação.

Casos de uso

Cuidados

A migração para a Nova Arquitetura é, em teoria, transparente para código JavaScript comum — a maior parte dos apps não precisa mudar nada. O risco está em bibliotecas nativas de terceiros ainda não adaptadas: módulos escritos apenas para a bridge antiga podem não funcionar, exigir uma versão mais recente ou precisar de uma camada de compatibilidade (interop layer) fornecida pelo próprio React Native. Antes de migrar um app existente, vale conferir se todas as dependências nativas já suportam Fabric e TurboModules.

Compatibilidade

JSI e Fabric começaram a ser expostos como opção experimental ainda na série 0.6x, mas a Nova Arquitetura só se tornou utilizável em produção a partir do React Native 0.68, de forma opcional. O bridgeless mode passou a ser o padrão quando a Nova Arquitetura está ativa a partir do React Native 0.74, e a própria Nova Arquitetura passou a vir habilitada por padrão em todo projeto novo a partir do React Native 0.76 (outubro de 2024). Projetos criados antes disso continuam na arquitetura antiga até serem migrados manualmente.

documentação oficial

Conclusão

A Nova Arquitetura não é uma feature isolada, mas uma reconstrução da comunicação entre JavaScript e código nativo: JSI elimina a bridge serializada, Fabric torna a renderização mais previsível e sincronizável, e TurboModules carrega módulos nativos só quando são realmente usados. Para quem escreve apps comuns, o ganho é performance e menos gambiarra; para quem escreve módulos nativos, é tipagem forte e chamadas síncronas de verdade.

Tecnologia:
react

Deixe seu Comentário!

Dúvida, sugestão ou só um "valeu!" — tudo é bem-vindo por aqui.

Comentário
Nome
Email
lock Seu e-mail não será publicado.