JSI: qué es, cómo funciona y arquitectura

Autor: IT Sectr Publicado: 2026-06-04 Tiempo de lectura: 10 min

JSI (JavaScript Interface) es una capa de software en React Native que proporciona acceso síncrono directo desde JavaScript a objetos y funciones de C++, reemplazando el puente JSON asíncrono Bridge. A diferencia de su predecesor, JSI permite llamar a métodos nativos sin serialización de mensajes y pasar referencias a objetos C++ directamente al entorno JS. Según React Native Team (2025), JSI proporciona hasta 10 veces más velocidad en la interacción JS-código nativo en escenarios con intercambio intensivo de datos.

Puntos clave

  • JSI — JavaScript Interface que proporciona acceso síncrono desde JS al código nativo C++
  • Acceso directo elimina la necesidad de serialización en JSON y cola de mensajes asíncrona
  • Rendimiento de la interacción JS-código nativo aumenta de 5 a 10 veces
  • Arquitectura JSI es la base de Fabric y TurboModules en la nueva arquitectura de React Native
  • Integración C++ permite conectar bibliotecas C++ arbitrarias sin envoltorios nativos

¿Qué es JSI?

JSI (JavaScript Interface) es una capa C++ que proporciona al motor JavaScript (Hermes, JavaScriptCore, V8) la capacidad de acceder directamente a objetos, funciones y memoria de C++. A diferencia de Bridge, que serializaba las llamadas en JSON y las pasaba a través de una cola asíncrona, JSI permite que el código JS llame sincrónicamente a métodos C++ y obtenga el resultado de inmediato.

JSI se introdujo en React Native 0.64 como parte de la Nueva Arquitectura. El objetivo principal era eliminar el cuello de botella que representaba Bridge: cada interacción entre JS y código nativo consumía tiempo en serialización, deserialización y paso a través de la cola de mensajes. JSI resuelve este problema dando al motor JS acceso directo a objetos C++ a través de envoltorios que implementan las interfaces jsi::Value, jsi::Object y jsi::Function.

JSI no es un reemplazo uno a uno de Bridge: es un enfoque fundamentalmente diferente para la integración. Bridge funcionaba como un buzón: JS enviaba un mensaje, pasaba por una cola, el lado nativo lo procesaba y enviaba una respuesta. JSI funciona como un puntero: JS obtiene una referencia a un objeto C++ y puede llamar a sus métodos sincrónicamente, como funciones JS normales. Esta es una diferencia fundamental en la arquitectura de interacción entre dos entornos.

Historia de creación

La necesidad de JSI surgió de las limitaciones del Bridge original, establecido en React Native 2015. A medida que el framework ganaba popularidad y las aplicaciones se volvían más complejas, el problema de rendimiento se hizo evidente: cada llamada a un módulo nativo requería al menos 3–5 ms para serialización. Para operaciones simples como leer el valor de un sensor u obtener el tamaño de pantalla, esto era aceptable, pero para animaciones, trabajo con gráficos y procesamiento de datos en flujo era crítico. El equipo de React Native comenzó a trabajar en la nueva arquitectura en 2019, y JSI se convirtió en su base.

Soporte de motores JavaScript

JSI está diseñada como una capa de abstracción sobre los motores JavaScript. Proporciona una API C++ unificada que se implementa para cada motor específico: Hermes, JavaScriptCore (iOS), V8 (Android). Esto significa que los desarrolladores no necesitan preocuparse por las diferencias entre motores: Fabric y TurboModules funcionan igual independientemente del motor JS que se use internamente.

¿Cómo funciona JSI?

En el núcleo de JSI se encuentra el concepto de Host Objects (objetos anfitrión): objetos C++ que se exportan al entorno JS como objetos JS nativos. Cuando el código JS accede a una propiedad o método de dicho objeto, JSI intercepta la llamada y la delega al método C++ correspondiente. Esto ocurre sincrónicamente, en el mismo hilo, sin cambio de contexto y sin asignar memoria para una cadena JSON.

Cada Host Object implementa la interfaz jsi::HostObject con los métodos get, set y getPropertyNames. El motor JS llama a estos métodos cada vez que se accede a una propiedad del objeto. Por ejemplo, al llamar a NativeModule.someMethod() en JS, JSI convierte esta llamada en una llamada C++ al método correspondiente del Host Object. El valor de retorno se pasa de vuelta a JS como jsi::Value, un tipo genérico que puede representar un número, cadena, booleano, objeto o undefined.

Una característica importante de JSI es la ausencia de cola de mensajes. Bridge usaba una cola asíncrona: JS enviaba una solicitud, cambiaba a otras tareas, el lado nativo procesaba la solicitud y el resultado se devolvía mediante un callback. JSI funciona sincrónicamente: si JS llama a un método de módulo nativo a través de JSI, la ejecución del código JS se pausa hasta que se recibe el resultado. Esto simplifica la lógica (no es necesario esperar callbacks) y elimina las condiciones de carrera, pero requiere precaución: las llamadas síncronas largas bloquean el hilo JS.

Ciclo de vida de los valores JSI

Los valores creados a través de JSI viven en el runtime del motor JS y son gestionados por el recolector de basura. Cuando el código C++ crea un jsi::String o jsi::Object y lo devuelve a JS, el entorno gestiona automáticamente la memoria. Si el código C++ quiere mantener una referencia a un valor JS entre llamadas, se usa jsi::Value::getWeak() o un jsi::Object::setProperty global con una referencia almacenada en el objeto raíz del runtime. Esto evita la eliminación prematura por el recolector de basura.

Seguridad de hilos

JSI no es segura para hilos por defecto. Todas las llamadas a métodos JSI deben ocurrir desde el hilo donde se ejecuta JS (normalmente el hilo JS de React Native). Si un módulo nativo inicia trabajo en segundo plano en un hilo separado, el resultado debe devolverse a través del hilo JS usando runOnJS de TurboModules. Esta limitación es el precio de la sincronía y la ausencia de serialización.

JSI vs Bridge: comparación

La diferencia entre JSI y Bridge es fundamental y afecta todos los aspectos de la interacción JS-código nativo. Bridge era asíncrono, serializaba datos en JSON y usaba una cola de mensajes; JSI es síncrono, trabaja con referencias nativas y no requiere serialización.

ParámetroBridgeJSI
Modelo de llamadaCola asíncronaLlamada directa síncrona
SerializaciónJSON (serialización + deserialización)Ninguna (referencias directas a objetos C++)
Latencia3–10 ms por llamada0.1–0.5 ms por llamada
TipificaciónDinámica (a través de JSON)Estática (a través de Codegen)
Integración C++Solo a través de módulos nativos (Java/ObjC)Directa, sin intermediarios
HiloHilo nativo separadoHilo JS (síncrono)

Según React Native Team, la migración de Bridge a JSI en la aplicación Facebook Marketplace redujo el tiempo de inicio en un 35% y disminuyó el consumo de memoria en un 20% al eliminar la duplicación de datos entre JS y el lado nativo.

Cuándo Bridge era necesario

Bridge no fue un “error”: fue una decisión arquitectónica justificada en el momento de la creación de React Native en 2015. El desarrollo nativo para dos plataformas con diferentes lenguajes requería un formato de intercambio universal. JSON como formato de serialización estaba disponible en todas las plataformas y permitía unificar la interacción. El problema se hizo evidente más tarde, cuando React Native comenzó a usarse para aplicaciones complejas con miles de llamadas a módulos nativos por segundo.

Compatibilidad hacia atrás

React Native mantiene compatibilidad hacia atrás: los módulos nativos escritos para Bridge continúan funcionando en la nueva arquitectura a través de una capa de compatibilidad. Sin embargo, para nuevos módulos se recomienda usar JSI directamente a través de TurboModules. La migración de módulos existentes implica reemplazar el protocolo de interacción sin cambiar la lógica de negocio del módulo.

JSI en la arquitectura de React Native

JSI es una capa fundamental sobre la que se construyen todos los componentes de la nueva arquitectura de React Native. Sin JSI no serían posibles ni Fabric (el nuevo renderizador) ni TurboModules (módulos nativos optimizados). JSI proporciona una forma unificada para que JS interactúe con C++ en todos los niveles.

Fabric y JSI

Fabric es el nuevo renderizador de React Native que usa JSI para acceso síncrono a representaciones C++ de la UI. En la arquitectura antigua, el renderizado pasaba por Bridge: JS creaba elementos React, los serializaba a JSON, los enviaba a través de Bridge, el lado nativo deserializaba y creaba la UI. Fabric a través de JSI crea objetos C++ Shadow Tree directamente desde JS, calcula sincrónicamente el Layout mediante Yoga y pasa los fotogramas listos al renderizador nativo, sin una sola serialización.

TurboModules y JSI

TurboModules es la evolución de los módulos nativos de React Native. En lugar de registrar un módulo en Bridge y llamar a sus métodos a través de JSON, TurboModules usa JSI para carga diferida e invocación directa. Cuando el código JS accede por primera vez a un módulo, JSI crea un Host Object que carga el módulo nativo y expone sus métodos como funciones C++. La carga diferida significa que el módulo no consume memoria hasta el primer acceso, lo que es especialmente importante para aplicaciones con docenas de módulos nativos, muchos de los cuales solo se usan en pantallas específicas.

Generación de código a través de JSI

Para trabajar con JSI en la nueva arquitectura se usa Codegen, una herramienta que genera envoltorios C++ a partir de especificaciones JavaScript. El desarrollador describe la interfaz del módulo nativo en TypeScript o Flow, y Codegen genera código C++ que implementa un Host Object compatible con JSI. Esto automatiza el trabajo rutinario y garantiza que los tipos en JS y C++ estén sincronizados.

Ejemplos de código con JSI

Veamos cómo es trabajar con JSI en la práctica. En este ejemplo, creamos una clase C++ simple que se exporta a JS a través de JSI y llamamos a su método desde código JavaScript en React Native.

cpp
// Calculator.h — encabezado de clase C++ accesible desde JS
class Calculator {
public:
    double add(double a, double b) { return a + b; }
    double multiply(double a, double b) { return a * b; }
};

La clase Calculator contiene dos métodos aritméticos. Necesitamos hacerla accesible desde JS. Para ello, se crea un Host Object que envuelve Calculator y expone sus métodos a través de JSI.

cpp
// CalculatorHostObject.cpp — implementación del envoltorio 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();
    }
};

En este código, el método get se llama cada vez que JS accede a una propiedad del objeto. Si el nombre de la propiedad es “add”, se devuelve una función C++ que toma dos argumentos de JS y llama a calc.add(). El valor se devuelve como jsi::Value: JSI convierte automáticamente double a un número JS.

Llamada desde JavaScript

Después de registrar el Host Object en el entorno JS, la llamada se ve como una función JS normal. Todos los tipos se verifican en la etapa de generación de código, eliminando errores de coincidencia de tipos durante la ejecución.

js
// JavaScript — llamando a la calculadora C++ a través de JSI
import { Calculator } from 'react-native-calculator'

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

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

Nota: el resultado se devuelve inmediatamente, sin Promise, sin await, sin callbacks. Esta es una llamada síncrona que era imposible en la arquitectura Bridge. Para operaciones largas (lectura de archivos, solicitud de red), se deben usar patrones asíncronos: JSI no elimina la necesidad de hilos en segundo plano para tareas pesadas.

En la práctica, la mayoría de los desarrolladores no escriben Host Objects JSI manualmente: este trabajo lo realiza Codegen, que genera envoltorios C++ basados en especificaciones TypeScript. Sin embargo, entender cómo funciona JSI internamente es necesario para la depuración efectiva del rendimiento y al crear módulos nativos complejos que requieren acceso directo a bibliotecas C++ (Skia, FFmpeg, OpenCV).

Preguntas frecuentes

¿En qué se diferencia JSI de Bridge en React Native?

Bridge funciona asíncronamente a través de serialización JSON y una cola de mensajes: cada llamada toma 3–10 ms para la conversión de datos. JSI proporciona acceso directo síncrono a objetos C++ sin serialización, reduciendo la latencia a 0.1–0.5 ms. JSI también admite pasar referencias a objetos en lugar de copias.

¿JSI soporta todos los motores JavaScript?

Sí, JSI proporciona una API C++ unificada implementada para Hermes (React Native por defecto), JavaScriptCore (iOS) y V8 (Android). Los desarrolladores no necesitan escribir código diferente para distintos motores: Fabric y TurboModules funcionan igual en todos los motores compatibles.

¿Se pueden usar módulos nativos antiguos con JSI?

Sí, React Native proporciona una capa de compatibilidad hacia atrás. Los módulos nativos escritos para Bridge continúan funcionando en la nueva arquitectura. Sin embargo, se recomienda migrarlos a TurboModules para obtener los beneficios de JSI: carga diferida y llamadas síncronas.

¿JSI requiere conocimientos de C++?

Para el desarrollo cotidiano, no. Las especificaciones TypeScript de los módulos nativos se compilan en envoltorios C++ automáticamente a través de Codegen. El conocimiento de C++ solo es necesario al crear bibliotecas C++ personalizadas o al depurar el rendimiento de JSI a nivel de runtime.

¿Qué problemas resuelve JSI?

JSI resuelve tres problemas clave de Bridge: alta latencia debido a la serialización JSON, falta de llamadas síncronas e imposibilidad de pasar objetos complejos por referencia. JSI también permite integrar bibliotecas C++ directamente, sin intermediarios Java u Objective-C.

Resumen

  • JSI (JavaScript Interface) — tecnología de acceso directo síncrono desde JavaScript a objetos C++ en React Native
  • Arquitectura JSI se basa en Host Objects: objetos C++ exportados a JS como objetos JS nativos
  • Rendimiento de las llamadas a través de JSI es 10–50 veces mayor que a través de Bridge, gracias a la ausencia de serialización
  • Fabric y TurboModules — componentes clave de la nueva arquitectura de React Native, construidos sobre JSI
  • Sincronía de JSI simplifica la lógica del código pero requiere precaución con operaciones largas
  • Integración C++ permite conectar cualquier biblioteca nativa sin envoltorios de plataforma
  • Use JSI para módulos nativos de alto rendimiento y migre los existentes desde Bridge

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también