Beyond the Bridge: Engineering High-Performance Native Modules with Nitro and the JSI
I dive deep into how Nitro and the JSI eliminate the JSON-serialization bottleneck in React Native. Discover how to build synchronous, type-safe native modules that perform at C++ speeds.

For years, building native modules in React Native felt like throwing data over a wall. We’d take our clean JavaScript objects, serialize them into a JSON string, shove them through a queue, and hope they landed safely on the other side. This is the 'Bridge' as we knew it, and frankly, it's been the primary bottleneck for every high-performance app I’ve ever engineered.
Today, I want to talk about the shift toward a Zero-JS Bridge architecture. By leveraging the JavaScript Interface (JSI) and the emerging Nitro Modules framework, we are moving into an era where JavaScript and C++ can finally share memory directly. No serialization. No queues. Just performance.
The Problem: The Serialization Tax
In the legacy architecture, every time you called a native function, the following happened:
- JS thread serializes arguments to JSON.
- Message is passed to the Bridge queue.
- Native thread picks up the message and deserializes it.
- Result is calculated, then serialized back to JSON.
- JS thread receives the response and deserializes it.
When you're trying to process camera frames at 60fps or synchronize complex animations, this 'tax' is fatal. You lose precious milliseconds just moving data.
Enter the JSI (JavaScript Interface)
The JSI is a lean C++ layer that allows us to expose native methods directly to the JavaScript engine (Hermes or V8). Instead of a message-passing system, JSI allows us to hold references to native objects in JavaScript.
I’ve found that the raw JSI is powerful but extremely verbose. Writing raw C++ bindings for every property and method is error-prone and tedious. This is where Nitro changes the game.
The Nitro Evolution
Nitro Modules (created by Marc Rousavy) is the next evolution of this concept. It acts as a high-performance, type-safe wrapper around the JSI. It uses a code-generation approach that allows us to define our interfaces in TypeScript, and it handles the heavy lifting of generating the C++, Swift, or Kotlin bindings.
Here is how I’m currently structuring these modules. First, we define the contract:
Nitro then generates the boilerplate. On the native side (Swift/C++), I can implement this logic synchronously. Because Nitro uses direct memory mapping via JSI, when I call calculator.multiply(5, 5), there is zero overhead. The JavaScript engine literally holds a pointer to the C++ function.
Why This Matters for Engineering
In my recent projects, switching to a Nitro/JSI architecture has unlocked three major breakthroughs:
- Synchronous Execution: We no longer have to
awaitevery native call. If a calculation needs to happen instantly to prevent a UI glitch, it happens on the same tick. - Shared Memory: For large data sets (like image buffers or large JSON-like trees), we can use
ArrayBuffersand share them between JS and C++ without copying the data. This reduces garbage collector pressure significantly. - Type Safety across the Boundary: The codegen ensures that if my TypeScript says a function returns a
string, the C++ implementation must match it. No more runtime crashes due to unexpectednullvalues from the bridge.
The Implementation Strategy
If you're looking to implement this in your own stack, don't try to migrate everything at once. Identify the hot paths. In my experience, these are usually:
- Image/Video processing logic.
- Database persistence layers (like SQLite bindings).
- Complex mathematical transformations for gestures.
Once you move these to a Nitro-powered JSI module, the performance delta is immediate. We went from 12ms overhead per bridge call to effectively 0.01ms. That is the difference between a 'good' app and a 'native-feeling' app.
Final Thoughts
The bridge is dying, and honestly, we should be celebrating. As React Native engineers, our goal is to make the abstraction as thin as possible. Nitro and the JSI are the sharpest tools we have for that job. It requires getting comfortable with a bit more C++ and native glue, but the performance gains are non-negotiable for high-tier engineering.