Fabric modernizes rendering, while JSI (JavaScript Interface) enables direct and more efficient communication between JavaScript and native or C++ code.

React Native's New Architecture represents a fundamental shift in how JavaScript communicates with native code. Fabric modernizes rendering, while JSI (JavaScript Interface) enables direct and more efficient communication between JavaScript and native or C++ code. Together with TurboModules and the new rendering pipeline, these technologies address important limitations of React Native's legacy bridge. But migration is not simply a matter of switching a configuration flag. Native modules, third-party dependencies, rendering assumptions, threading behavior, and application performance can all change. A successful migration requires understanding what is changing, identifying compatibility risks early, and moving toward the new architecture incrementally rather than treating it as a one-day upgrade.
The original React Native architecture relied heavily on a centralized bridge between JavaScript and native code.
A simplified representation looks like:
JavaScript
│
▼
Bridge
│
▼
Native Code
│
▼
Platform APIsThe bridge made it possible to build native experiences using JavaScript, but communication across the boundary could become expensive for applications with heavy interaction between JavaScript and native code.
The limitations became more noticeable with applications involving:
Frequent native calls
Complex animations
Large data transfers
Real-time interactions
Native-heavy libraries
High-frequency UI updates
The New Architecture changes this model.
Instead of relying on the same centralized communication mechanism, React Native moves toward:
JavaScript
│
▼
JSI
│
├── Fabric
├── TurboModules
└── C++ / NativeThis creates a more direct and flexible foundation for communication between JavaScript and native systems.
The difference can be simplified like this.
JavaScript
↓
Bridge
↓
Serialized Messages
↓
NativeJavaScript
↓
JSI
↓
Native / C++The goal is not simply to remove one layer.
The New Architecture also changes how React Native handles:
Rendering
Native modules
Threading
Component updates
Data communication
This makes the architecture more capable—but also means migration requires more than changing one setting.
Fabric is React Native's modern rendering architecture.
Its purpose is to make the rendering system more flexible and better aligned with modern React.
A simplified flow is:
React
↓
Component Tree
↓
Fabric Renderer
↓
Native View
↓
iOS / Android UIFabric is designed around a more modern rendering pipeline and supports tighter integration between React's rendering model and native UI.
This matters for applications with:
Complex interfaces
Frequent updates
Animations
Large component trees
Concurrent rendering patterns
The important conceptual shift is:
Fabric is not simply a faster version of the old renderer. It is a redesigned rendering foundation.
That means native components and libraries that make assumptions about the old rendering system may need updates.
JSI stands for JavaScript Interface.
It provides a mechanism for JavaScript to interact more directly with native and C++ code.
Instead of:
JavaScript
↓
Serialization
↓
Bridge
↓
NativeJSI enables a model closer to:
JavaScript
↓
JSI
↓
C++ / NativeThis can reduce communication overhead for certain workloads.
The biggest benefit is not simply "fewer milliseconds."
It is the architectural flexibility that comes from allowing JavaScript and native code to communicate without depending on the same serialized bridge model.
This becomes particularly useful for:
High-performance native libraries
Animations
Database engines
Cryptography
Image processing
Storage systems
Native SDK integrations
The New Architecture also introduces TurboModules as the modern approach to native modules.
Conceptually:
React Native
│
▼
TurboModule
│
▼
Native ImplementationCompared with traditional Native Modules, TurboModules are designed to work more closely with the New Architecture and JSI.
They can support:
Lazy loading
Typed interfaces
More direct native communication
Better integration with the modern runtime
A broader architecture looks like:
JavaScript
│
JSI
┌───────┼────────┐
▼ ▼ ▼
Fabric TurboModules C++
│ │ │
└───────┼────────┘
▼
Native APIsFabric handles rendering.
TurboModules handle native modules.
JSI provides the underlying interface for direct communication.
Together, these pieces form the foundation of the New Architecture.
For a simple application, the difference may not immediately be visible.
For a complex React Native product, the benefits can become much more meaningful.
Potential advantages include:
Better rendering architecture
Improved native interoperability
More efficient JavaScript-to-native communication
Modern React integration
Better foundations for high-performance libraries
More scalable native module architecture
The bigger strategic advantage is ecosystem alignment.
As React Native's ecosystem increasingly targets the New Architecture, staying indefinitely on legacy infrastructure can become more difficult.
The migration question therefore becomes:
Do we want to move when the application is ready, or wait until a critical dependency forces the move?
Before changing architecture, inventory the application.
Start with:
React Native Version
↓
Native Dependencies
↓
Custom Native Modules
↓
Third-Party Libraries
↓
Native UI Components
↓
Build ConfigurationLook for dependencies involving:
Android native code
iOS native code
C++
Custom ViewManagers
Native Modules
Old bridge APIs
Native event systems
Also identify libraries responsible for critical functionality:
Navigation
Animations
Storage
Networking
Maps
Payments
Camera
Push notifications
Analytics
The goal is to answer:
What parts of the application actually cross the JavaScript-native boundary?
That is where migration risk is concentrated.
Third-party libraries are often the biggest migration variable.
Your application might depend on:
React Native App
│
┌───┼───────────────┐
▼ ▼ ▼
Maps Payments Storage
│ │ │
└─────┼──────────────┘
▼
Native CodeIf one of these dependencies does not support the New Architecture properly, migration can become difficult.
Create a compatibility inventory:
| Dependency | Native Code | New Architecture Support | Risk | | ---------- | ----------: | -----------------------: | -----: | | Navigation | Yes | Check current version | Medium | | Storage | Yes | Check current version | Medium | | Payments | Yes | Vendor-dependent | High | | Analytics | Yes | Vendor-dependent | Medium | | UI Library | Yes | Check compatibility | Medium |
The exact status should always be verified against the dependency's current documentation and release version.
Do not assume that a popular library is automatically compatible.
Custom native modules deserve special attention.
A legacy module might look conceptually like:
JavaScript
↓
Native Module
↓
Bridge
↓
iOS / AndroidThe modern architecture becomes closer to:
JavaScript
↓
JSI / TurboModule
↓
Native ImplementationMigration often involves:
Defining a typed interface
Generating native bindings
Updating native implementations
Updating registration
Validating lifecycle behavior
Testing asynchronous operations
The important lesson is:
Do not treat native modules as implementation details during migration. They are architecture boundaries.
Fabric can expose assumptions hidden inside older native components.
A custom component might previously assume:
React Update
↓
Legacy Renderer
↓
Native ViewUnder Fabric:
React Update
↓
Fabric
↓
Native ComponentThis can affect:
View lifecycle
Property updates
Event handling
Measurement
Layout
Native component registration
Custom native UI should therefore be tested thoroughly.
Pay particular attention to components that:
Measure themselves
Manipulate native views directly
Depend on layout timing
Integrate with gesture systems
Perform high-frequency updates
The New Architecture changes more than communication.
Modern React Native applications may involve:
JavaScript
│
├── UI
├── Native
└── Background Work
│
▼
NativeDevelopers need to understand where work is happening.
A common mistake is assuming:
"JSI means everything is automatically faster."
It does not.
If you perform expensive work on the wrong thread, you can still create:
Frame drops
Input latency
UI freezes
High CPU usage
Memory pressure
The goal is to place work appropriately:
UI-Critical Work
↓
UI-Safe Execution
Heavy Work
↓
Background / Native ProcessingArchitecture still matters more than a technology label.
Do not validate the New Architecture only by checking whether the application launches.
Test:
Screen transitions
Layouts
Animations
Lists
Gestures
Camera
Maps
Payments
Notifications
Storage
Startup time
Frame rate
Memory
CPU
Interaction latency
Background/foreground transitions
Network failures
Deep links
Push notifications
Device-specific behavior
A useful comparison is:
Legacy Architecture
↓
Baseline Metrics
↓
New Architecture
↓
CompareDo not assume migration is successful simply because the app builds.
Simulator testing is useful, but it is not enough.
Real devices reveal:
Memory pressure
CPU limitations
GPU behavior
OS-specific differences
Thermal throttling
Background execution behavior
A performance-sensitive migration should test representative devices:
High-End Device
Mid-Range Device
Older Supported DeviceThe user experience is ultimately what matters.
Enabling the New Architecture is only the beginning.
One incompatible dependency can block the entire migration.
Large migrations are easier to debug when broken into manageable stages.
JSI enables different communication patterns. Your implementation still determines performance.
Native rendering and performance issues often appear differently on real devices.
Legacy assumptions can hide inside ViewManagers and native UI code.
Look at:
Frame rate
Interaction latency
Memory
CPU
Native call performance
Crash rates
Always maintain a clear path back to the known-good architecture during migration.
A New Architecture application can be visualized as:
React Application
│
┌────────┴────────┐
▼ ▼
Server / JS Logic UI Components
│ │
└────────┬────────┘
▼
JSI
┌──────────┼──────────┐
▼ ▼ ▼
Fabric TurboModules C++
│ │ │
└──────────┼──────────┘
▼
Native Platform
/ \
iOS AndroidThe architecture creates clearer boundaries between:
React
Rendering
Native modules
C++
Platform APIs
That separation becomes particularly valuable as applications grow.
The safest approach is incremental.
Measure:
Startup
Memory
CPU
Frame performance
Crash rate
Build time
Identify native libraries and custom modules.
Move toward versions that support the New Architecture.
Identify bridge-specific assumptions.
Do not begin with production.
Test both JavaScript and native behavior.
Include representative hardware.
Release to a limited percentage of users where your deployment process supports it.
Watch:
Crashes
ANRs
Performance
Memory
Native errors
User reports
Only increase rollout after the new architecture demonstrates stable behavior.
The migration becomes especially compelling when your application has:
Complex native integrations
Performance-sensitive UI
Heavy native communication
Large component trees
Custom native modules
Long-term React Native maintenance requirements
It can also be strategically important when your dependencies and framework ecosystem increasingly assume the New Architecture.
For a simple application with few native integrations, the immediate performance improvement may be modest.
In that case, migration should still be evaluated based on:
Maintenance
Dependency compatibility
Future upgrades
Long-term platform strategy
Engineering leaders planning the migration should ask:
How much native code does our application actually depend on?
Which dependencies are currently blocking the New Architecture?
Do we have custom Native Modules or ViewManagers?
What performance problems are we trying to solve?
What does the current architecture cost us in maintenance?
Can we measure the application's behavior before and after migration?
Do we have a controlled rollout and rollback strategy?Most importantly:
Are we migrating because the new architecture solves a real technical problem—or simply because it is the latest architecture?
The answer should determine the migration timeline.
Migrating to React Native's New Architecture is a shift in how the application communicates, renders, and interacts with native code.
The old model:
JavaScript
↓
Bridge
↓
Nativemoves toward:
JavaScript
↓
JSI
├── Fabric
├── TurboModules
└── Native / C++The benefits can be significant:
More modern rendering
More direct native interoperability
Better foundations for high-performance applications
A more scalable native module model
But the migration has real engineering complexity.
Audit dependencies first.
Identify custom native code.
Understand rendering assumptions.
Measure performance before changing architecture.
Test real devices.
Migrate incrementally.
Monitor production carefully.
And maintain a rollback strategy.
The New Architecture should not be treated as a checkbox. It is an architectural migration—and successful migrations are measured by reliability, maintainability, and user experience, not simply by whether a build succeeds.
Fabric provides the modern rendering foundation.
JSI enables more direct JavaScript-to-native interaction.
TurboModules modernize native module integration.
Together, they give React Native a stronger foundation for increasingly sophisticated mobile applications.
The smartest migration is therefore not the fastest migration. It is the one that gives your team a clear understanding of every native boundary, proves the new architecture against real application workloads, and gradually moves the product forward without turning a framework upgrade into a production-risk event.
We build custom software, mobile apps, and web platforms for startups and enterprises.



Their team became an extension of ours — within months they'd rebuilt our entire product experience from the ground up.
