Zero-Bridge Native Modules with JSI: A Performance Boost
Learn how the JavaScript Interface (JSI) lets you call native code without the React Native bridge, cutting latency and improving UI responsiveness.
Insight
The traditional React Native bridge serializes data between JavaScript and native threads, adding measurable latency—especially for high‑frequency calls like sensor streams or cryptographic work. JSI (JavaScript Interface) removes that bottleneck by exposing native objects directly to the JavaScript engine, allowing zero‑copy calls. When you register a JSI module, its methods run on the same thread as the JS runtime, delivering near‑native speed while keeping the familiar JS API.
Example
// MyTimerModule.cpp (C++)
#include <jsi/jsi.h>
using namespace facebook::jsi;
void installTimer(Runtime& rt) {
Function timer = Function::createFromHostFunction(
rt, "setFastTimer", 2,
[](Runtime& rt, const Value&, const Value* args, size_t count) -> Value {
int ms = args[0].asNumber();
Function cb = args[1].getObject(rt).asFunction(rt);
// native timer implementation without bridge
std::thread([ms, cb, &rt]() {
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
rt.call(cb, {});
}).detach();
return Value::undefined();
}
);
rt.global().setProperty(rt, "setFastTimer", std::move(timer));
}
// usage in React Native (TSX)
import { useEffect } from 'react';
declare const setFastTimer: (ms: number, cb: () => void) => void;
useEffect(() => {
setFastTimer(100, () => console.log('fast tick'));
}, []);
Takeaway
When you need ultra‑low latency or high‑frequency native calls, replace bridge‑based modules with a small JSI wrapper. The API stays JavaScript‑friendly, but you gain native‑level performance without sacrificing the React Native development experience.