Day 32: RN New Architecture: JSI (JavaScript Interface) Overview
Understand JSI as a synchronous, direct-memory-reference bridge replacement, and why it removes serialization from the equation entirely.
Study
Concepts
JSI: C++ objects that JS can hold direct references to
JSI (JavaScript Interface) is a lightweight C++ layer that lets JavaScript hold a direct reference to a C++ Host Object and call its methods SYNCHRONOUSLY, with no JSON serialization and no async queue — it replaces the Bridge's "send a message, wait for a batched async response" model with "call a function and get the return value immediately", the same way calling a regular JS function works.
Because JSI is engine-agnostic (it is not tied to JavaScriptCore), it is also what unlocked swapping in Hermes (Meta's JS engine built for RN, Day 39) without touching the app-facing API — the New Architecture and Hermes adoption are separate but related upgrades that both flow through JSI.
What this actually removes: the serialization tax
With JSI, a native module can expose a Host Object whose methods JS calls directly — no JSON.stringify, no message queue, no waiting for the next batch. This is what makes previously-impossible synchronous native calls possible (e.g. reading a value from native storage and using it in the very next line of JS), and it is the foundation TurboModules and Fabric (Day 33) are built on top of.
JSI does not eliminate threading — the JS thread and native UI thread still exist and still need coordination for thread-safety — but it eliminates the SERIALIZATION and QUEUEING overhead that made every single cross-boundary call costly regardless of urgency.
See It
Visualizations
Visualization
Bridge vs JSI
| Old: The Bridge | New: JSI | |
|---|---|---|
| Call style | Async only, message-based | Synchronous OR async, direct call |
| Data format | JSON-serialized | Direct C++ object references, no serialization |
| Batching/queueing | Yes — added latency | None required for the call itself |
| Engine coupling | Assumes JavaScriptCore | Engine-agnostic (enables Hermes) |
| Enables | — | TurboModules, Fabric, synchronous native calls |
Visualization
New Architecture: JS talks to Host Objects directly via JSI
Build It
Code Examples
Conceptual shape: a JSI Host Object exposed to JS (C++)
// Simplified illustration of a JSI Host Object — real code has more
// boilerplate, but this is the core idea: expose C++ methods that JS
// can call directly, synchronously, no serialization involved.
class DeviceInfoHostObject : public jsi::HostObject {
public:
jsi::Value get(jsi::Runtime& rt, const jsi::PropNameID& name) override {
auto propName = name.utf8(rt);
if (propName == "getBatteryLevelSync") {
return jsi::Function::createFromHostFunction(
rt, name, 0,
[](jsi::Runtime& rt, const jsi::Value&, const jsi::Value*, size_t) {
double level = readBatteryLevelFromOS(); // real native call
return jsi::Value(level); // returned IMMEDIATELY, no async needed
});
}
return jsi::Value::undefined();
}
};What this enables at the JS call site
// Old Bridge: always async, even for data the OS has instantly
const level = await DeviceInfo.getBatteryLevel();
// New Architecture / JSI-backed module: can be truly synchronous
const level = DeviceInfo.getBatteryLevelSync(); // returns immediately, like a normal function callRemember
Key Takeaways
- JSI replaces JSON-message-passing with direct C++ object references JS can call synchronously.
- This removes the serialization + queueing tax that made every Bridge call costly, regardless of how simple the call was.
- JSI is engine-agnostic — it is the layer that made adopting Hermes possible without changing the app-facing API.
- Threading still exists and still matters for safety — JSI removes serialization overhead, not the need for thread coordination.
- TurboModules and Fabric (Day 33) are built directly on top of JSI — it is the foundational layer of the New Architecture.
Do It
Practice
- 1Read the official React Native "Understanding JSI" documentation and summarize the Host Object concept in 3 sentences, in your own words.
- 2List two features in a real app you've worked on that would have benefited from a synchronous native call instead of an async Bridge round trip.
- 3Diagram (on paper) the old Bridge flow vs the new JSI flow side by side for the same "read a native value" operation.