JSI: o que é, princípio de funcionamento e arquitetura

Autor: IT Sectr Publicado: 2026-06-04 Tempo de leitura: 10 min

JSI (JavaScript Interface) é uma camada de software no React Native que fornece acesso síncrono direto de JavaScript a objetos e funções C++, substituindo a ponte JSON assíncrona Bridge. Ao contrário do seu predecessor, o JSI permite chamar métodos nativos sem serialização de mensagens e passar referências a objetos C++ diretamente para o ambiente JS. De acordo com React Native Team (2025), o JSI proporciona uma aceleração de até 10 vezes na interação JS-código nativo em cenários com intensa troca de dados.

Pontos principais

  • JSI — JavaScript Interface que fornece acesso síncrono de JS ao código nativo C++
  • Acesso direto elimina a necessidade de serialização em JSON e fila de mensagens assíncrona
  • Desempenho da interação JS-código nativo aumenta de 5 a 10 vezes
  • Arquitetura JSI é a base do Fabric e TurboModules na nova arquitetura do React Native
  • Integração C++ permite conectar bibliotecas C++ arbitrárias sem wrappers nativos

O que é JSI?

JSI (JavaScript Interface) é uma camada C++ que fornece ao motor JavaScript (Hermes, JavaScriptCore, V8) a capacidade de acessar diretamente objetos, funções e memória C++. Ao contrário do Bridge, que serializava chamadas em JSON e as passava através de uma fila assíncrona, o JSI permite que o código JS chame métodos C++ de forma síncrona e obtenha o resultado imediatamente.

O JSI foi introduzido no React Native 0.64 como parte da Nova Arquitetura. O objetivo principal era eliminar o gargalo que o Bridge representava: cada interação entre JS e código nativo consumia tempo em serialização, desserialização e passagem pela fila de mensagens. O JSI resolve esse problema dando ao motor JS acesso direto a objetos C++ através de wrappers que implementam as interfaces jsi::Value, jsi::Object e jsi::Function.

O JSI não é uma substituição um a um do Bridge — é uma abordagem fundamentalmente diferente para integração. O Bridge funcionava como uma caixa de correio: JS enviava uma mensagem, ela passava por uma fila, o lado nativo processava e enviava uma resposta. O JSI funciona como um ponteiro: JS obtém uma referência a um objeto C++ e pode chamar seus métodos de forma síncrona, como funções JS normais. Esta é uma diferença fundamental na arquitetura de interação entre dois ambientes.

História da criação

A necessidade do JSI surgiu das limitações do Bridge original, estabelecido no React Native 2015. À medida que o framework ganhava popularidade e as aplicações se tornavam mais complexas, o problema de desempenho tornou-se evidente: cada chamada a um módulo nativo exigia pelo menos 3–5 ms para serialização. Para operações simples como ler o valor de um sensor ou obter o tamanho da tela, isso era aceitável, mas para animações, trabalho com gráficos e processamento de dados em fluxo — era crítico. A equipe do React Native começou a trabalhar na nova arquitetura em 2019, e o JSI tornou-se sua base.

Suporte a motores JavaScript

O JSI é projetado como uma camada de abstração sobre os motores JavaScript. Ele fornece uma API C++ unificada que é implementada para cada motor específico: Hermes, JavaScriptCore (iOS), V8 (Android). Isso significa que os desenvolvedores não precisam se preocupar com as diferenças entre os motores — o Fabric e os TurboModules funcionam da mesma forma independentemente do motor JS usado internamente.

Como funciona o JSI?

No núcleo do JSI está o conceito de Host Objects (objetos anfitriões) — objetos C++ que são exportados para o ambiente JS como objetos JS nativos. Quando o código JS acessa uma propriedade ou método de tal objeto, o JSI intercepta a chamada e a delega ao método C++ correspondente. Isso ocorre de forma síncrona, na mesma thread, sem troca de contexto e sem alocar memória para uma string JSON.

Cada Host Object implementa a interface jsi::HostObject com os métodos get, set e getPropertyNames. O motor JS chama esses métodos toda vez que uma propriedade do objeto é acessada. Por exemplo, ao chamar NativeModule.someMethod() em JS, o JSI converte esta chamada em uma chamada C++ para o método correspondente do Host Object. O valor de retorno é passado de volta para JS como jsi::Value — um tipo genérico que pode representar um número, string, booleano, objeto ou undefined.

Uma característica importante do JSI é a ausência de fila de mensagens. O Bridge usava uma fila assíncrona: JS enviava uma solicitação, mudava para outras tarefas, o lado nativo processava a solicitação e o resultado era retornado através de um callback. O JSI funciona de forma síncrona: se JS chama um método de módulo nativo através do JSI, a execução do código JS é pausada até que o resultado seja recebido. Isso simplifica a lógica (não é necessário esperar callbacks) e elimina condições de corrida, mas requer cautela — chamadas síncronas longas bloqueiam a thread JS.

Ciclo de vida dos valores JSI

Os valores criados através do JSI vivem no runtime do motor JS e são gerenciados pelo coletor de lixo. Quando o código C++ cria um jsi::String ou jsi::Object e o retorna para JS, o ambiente gerencia automaticamente a memória. Se o código C++ quiser manter uma referência a um valor JS entre chamadas, usa-se jsi::Value::getWeak() ou um jsi::Object::setProperty global com uma referência armazenada no objeto raiz do runtime. Isso evita a remoção prematura pelo coletor de lixo.

Segurança de threads

O JSI não é seguro para threads por padrão. Todas as chamadas de métodos JSI devem ocorrer da thread onde o JS é executado (normalmente a thread JS do React Native). Se um módulo nativo inicia trabalho em segundo plano em uma thread separada, o resultado deve ser retornado através da thread JS usando runOnJS dos TurboModules. Esta limitação é o preço da síncronia e da ausência de serialização.

JSI vs Bridge: comparação

A diferença entre JSI e Bridge é fundamental e afeta todos os aspectos da interação JS-código nativo. O Bridge era assíncrono, serializava dados em JSON e usava uma fila de mensagens; o JSI é síncrono, trabalha com referências nativas e não requer serialização.

ParâmetroBridgeJSI
Modelo de chamadaFila assíncronaChamada direta síncrona
SerializaçãoJSON (serialização + desserialização)Nenhuma (referências diretas a objetos C++)
Latência3–10 ms por chamada0.1–0.5 ms por chamada
TipagemDinâmica (via JSON)Estática (via Codegen)
Integração C++Apenas através de módulos nativos (Java/ObjC)Direta, sem intermediários
ThreadThread nativa separadaThread JS (síncrona)

De acordo com a React Native Team, a migração do Bridge para o JSI no aplicativo Facebook Marketplace reduziu o tempo de inicialização em 35% e diminuiu o consumo de memória em 20% ao eliminar a duplicação de dados entre os lados JS e nativo.

Quando o Bridge era necessário

O Bridge não foi um “erro” — foi uma decisão arquitetural justificada no momento da criação do React Native em 2015. O desenvolvimento nativo para duas plataformas com linguagens diferentes exigia um formato de intercâmbio universal. O JSON como formato de serialização estava disponível em todas as plataformas e permitia unificar a interação. O problema tornou-se evidente mais tarde, quando o React Native começou a ser usado para aplicações complexas com milhares de chamadas a módulos nativos por segundo.

Compatibilidade reversa

O React Native mantém compatibilidade reversa: os módulos nativos escritos para o Bridge continuam funcionando na nova arquitetura através de uma camada de compatibilidade. No entanto, para novos módulos, recomenda-se usar o JSI diretamente através dos TurboModules. A migração de módulos existentes envolve substituir o protocolo de interação sem alterar a lógica de negócio do módulo.

JSI na arquitetura do React Native

O JSI é uma camada fundamental sobre a qual todos os componentes da nova arquitetura do React Native são construídos. Sem o JSI, nem o Fabric (o novo renderizador) nem os TurboModules (módulos nativos otimizados) seriam possíveis. O JSI fornece uma forma unificada para o JS interagir com C++ em todos os níveis.

Fabric e JSI

O Fabric é o novo renderizador do React Native que usa o JSI para acesso síncrono a representações C++ da UI. Na arquitetura antiga, a renderização passava pelo Bridge: JS criava elementos React, serializava-os em JSON, enviava-os através do Bridge, o lado nativo desserializava e criava a UI. O Fabric através do JSI cria objetos C++ Shadow Tree diretamente do JS, calcula sincronamente o Layout através do Yoga e passa os quadros prontos para o renderizador nativo — sem uma única serialização.

TurboModules e JSI

Os TurboModules são a evolução dos módulos nativos do React Native. Em vez de registrar um módulo no Bridge e chamar seus métodos através de JSON, os TurboModules usam o JSI para carregamento lento e invocação direta. Quando o código JS acessa um módulo pela primeira vez, o JSI cria um Host Object — ele carrega o módulo nativo e expõe seus métodos como funções C++. O carregamento lento significa que o módulo não consome memória até o primeiro acesso — isso é especialmente importante para aplicações com dezenas de módulos nativos, muitos dos quais são usados apenas em telas específicas.

Geração de código através do JSI

Para trabalhar com o JSI na nova arquitetura, usa-se o Codegen — uma ferramenta que gera bindings C++ a partir de especificações JavaScript. O desenvolvedor descreve a interface do módulo nativo em TypeScript ou Flow, e o Codegen gera código C++ implementando um Host Object compatível com JSI. Isso automatiza o trabalho rotineiro e garante que os tipos nos lados JS e C++ estejam sincronizados.

Exemplos de código com JSI

Vamos ver como é trabalhar com o JSI na prática. Neste exemplo, criamos uma classe C++ simples que é exportada para JS através do JSI e chamamos seu método a partir do código JavaScript no React Native.

cpp
// Calculator.h — cabeçalho de classe C++ acessível de JS
class Calculator {
public:
    double add(double a, double b) { return a + b; }
    double multiply(double a, double b) { return a * b; }
};

A classe Calculator contém dois métodos aritméticos. Precisamos torná-la acessível a partir do JS. Para isso, é criado um Host Object que envolve a Calculator e expõe seus métodos através do JSI.

cpp
// CalculatorHostObject.cpp — implementação do wrapper JSI
class CalculatorHostObject : public jsi::HostObject {
private:
    Calculator calc;

public:
    jsi::Value get(jsi::Runtime& runtime,
        const jsi::PropNameID& name) override {
        auto propName = name.utf8(runtime);

        if (propName == "add") {
            return jsi::Function::createFromHostFunction(
                runtime, name, 2,
                [this](jsi::Runtime& runtime,
                    const jsi::Value& thisVal,
                    const jsi::Value* args,
                    size_t count) -> jsi::Value {
                    return jsi::Value(calc.add(
                        args[0].asNumber(),
                        args[1].asNumber()));
                });
        }
        return jsi::Value::undefined();
    }
};

Neste código, o método get é chamado toda vez que o JS acessa uma propriedade do objeto. Se o nome da propriedade for “add”, uma função C++ é retornada que recebe dois argumentos do JS e chama calc.add(). O valor é retornado como jsi::Value — o JSI converte automaticamente double para um número JS.

Chamada a partir do JavaScript

Após registrar o Host Object no ambiente JS, a chamada parece uma função JS normal. Todos os tipos são verificados no estágio de geração de código, eliminando erros de incompatibilidade de tipos durante a execução.

js
// JavaScript — chamando calculadora C++ via JSI
import { Calculator } from 'react-native-calculator'

const result = Calculator.add(5, 3)
console.log(result) // 8 — síncrono, sem atraso

const product = Calculator.multiply(4, 2.5)
console.log(product) // 10 — resultado imediato

Nota: o resultado é retornado imediatamente, sem Promise, sem await, sem callbacks. Esta é uma chamada síncrona que era impossível na arquitetura Bridge. Para operações longas (leitura de arquivo, requisição de rede), devem ser usados padrões assíncronos — o JSI não elimina a necessidade de threads em segundo plano para tarefas pesadas.

Na prática, a maioria dos desenvolvedores não escreve Host Objects JSI manualmente — este trabalho é feito pelo Codegen, que gera wrappers C++ baseados em especificações TypeScript. No entanto, entender como o JSI funciona internamente é necessário para a depuração eficaz de desempenho e ao criar módulos nativos complexos que exigem acesso direto a bibliotecas C++ (Skia, FFmpeg, OpenCV).

Perguntas frequentes

Como o JSI difere do Bridge no React Native?

O Bridge funciona de forma assíncrona através de serialização JSON e uma fila de mensagens — cada chamada leva 3–10 ms para conversão de dados. O JSI fornece acesso direto síncrono a objetos C++ sem serialização, reduzindo a latência para 0.1–0.5 ms. O JSI também suporta passar referências de objetos em vez de cópias.

O JSI suporta todos os motores JavaScript?

Sim, o JSI fornece uma API C++ unificada implementada para Hermes (padrão do React Native), JavaScriptCore (iOS) e V8 (Android). Os desenvolvedores não precisam escrever código diferente para motores diferentes — o Fabric e os TurboModules funcionam igualmente em todos os motores suportados.

Módulos nativos antigos podem ser usados com o JSI?

Sim, o React Native fornece uma camada de compatibilidade reversa. Módulos nativos escritos para o Bridge continuam funcionando na nova arquitetura. No entanto, recomenda-se migrá-los para os TurboModules para obter os benefícios do JSI — carregamento lento e chamadas síncronas.

O JSI requer conhecimento de C++?

Para o desenvolvimento diário — não. As especificações TypeScript dos módulos nativos são compiladas em bindings C++ automaticamente através do Codegen. O conhecimento de C++ é necessário apenas ao criar bibliotecas C++ personalizadas ou ao depurar o desempenho do JSI no nível do runtime.

Quais problemas o JSI resolve?

O JSI resolve três problemas principais do Bridge: alta latência devido à serialização JSON, falta de chamadas síncronas e impossibilidade de passar objetos complexos por referência. O JSI também permite integrar bibliotecas C++ diretamente, sem intermediários Java ou Objective-C.

Resumo

  • JSI (JavaScript Interface) — tecnologia de acesso direto síncrono de JavaScript a objetos C++ no React Native
  • Arquitetura JSI é baseada em Host Objects — objetos C++ exportados para JS como objetos JS nativos
  • Desempenho de chamadas através do JSI é 10–50 vezes maior que através do Bridge, devido à ausência de serialização
  • Fabric e TurboModules — componentes-chave da nova arquitetura do React Native, construídos sobre o JSI
  • Sincronia do JSI simplifica a lógica do código mas requer cautela com operações longas
  • Integração C++ permite conectar qualquer biblioteca nativa sem wrappers de plataforma
  • Use JSI para módulos nativos de alto desempenho e migre os existentes do Bridge

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também