Fabric is a new React Native renderer, completely rewritten in C++ and integrated with JSI. It replaced the old rendering based on UIView and ViewManager, providing synchronous UI updates and efficient change computation through Shadow Tree. According to Meta Engineering Blog, 2024, Fabric is a mandatory component of the new architecture and is available in React Native 0.76+.
Key Takeaways
Fabric is a new rendering system for React Native that replaced the old renderer, which worked through Shadow Thread and Bridge. In the old architecture, the rendering process involved three steps: JavaScript computes Virtual DOM, Shadow Thread (Yoga) calculates the layout, Native Thread draws UIView. Fabric combines all these steps into a single C++ pipeline that works synchronously.
Fabric development began in 2019 as part of the Lean Core initiative and the “The New Architecture” project. The main goal was to solve performance problems associated with asynchronous three-round rendering. In the old architecture, each state change required three passes through different threads, creating a delay between data change and UI rendering.
Fabric is based on the concept of an Immutable Shadow Tree. Each tree node represents a React component with its props and state. When state changes, a new tree is created, and Fabric computes the difference between the old and new tree and applies only the necessary changes to the native UI. This minimizes the number of UIView/ViewGroup operations and reduces rendering time.
Shadow Tree is the foundation of Fabric’s operation. Unlike the old architecture, where the Shadow Tree existed only on the C++ side and was separated from the JS tree through the async Bridge, Fabric creates a fully synchronized hierarchical representation of the UI. Shadow Tree nodes store component props, state, and styles, while Yoga calculates the layout directly at the C++ level.
When a React component updates its state, React Native sends a new Shadow Node to Fabric. Fabric does not re-render the entire UI — it uses a diffing algorithm at the C++ level to determine which nodes have changed. Only changed nodes are sent for native rendering, which significantly reduces the amount of work.
The rendering process in Fabric consists of three phases that execute synchronously at the C++ level without thread switching. The first phase is Render: React calls the component’s render function, which returns a React Element Tree. The second phase is Commit: React Native creates a new Shadow Tree and computes changes based on the old version. The third phase is Mount: Fabric applies changes to the native UI, creating, updating, or deleting UIViews.
All three phases work as a single pipeline where data is transferred through JSI without serialization. This is a key difference from the old architecture, where there were gaps between phases: JS → (JSON) → Shadow Thread → (layout) → Native Thread.
The comparison of Fabric with the old renderer demonstrates how significantly the React Native architecture has changed. The old renderer worked asynchronously, splitting the rendering process across three independent threads. Fabric combines everything into a single C++ pipeline.
| Characteristic | Old Renderer | Fabric |
|---|---|---|
| Architecture | Three threads (JS, Shadow, Native) | Single C++ pipeline |
| Synchrony | Asynchronous rendering | Synchronous rendering |
| Shadow Tree | Mutable, each thread has its own copy | Immutable, unified |
| Channels | Bridge + JSON serialization | JSI + direct C++ call |
| Performance | Up to 16 ms delay per frame | Less than 1 ms delay per frame |
In practice, Fabric is especially beneficial for applications with frequent UI updates: animations, scrolls with floating headers, real-time data. For static pages (text, buttons) the difference is less noticeable. According to Meta benchmarks, Fabric reduces initial list rendering time by 40–60%.
JSI (JavaScript Interface) is a key component that makes Fabric possible. Through JSI, Fabric gets direct access to JavaScript values without serialization. When React passes props to Fabric, they are not copied through JSON — JSI passes pointers to data in the JS engine’s memory.
The JSI architecture allows Fabric to work with any JavaScript engine — Hermes, JSC, or V8. The Fabric C++ code does not depend on a specific JS engine implementation, which simplifies maintenance and testing. All UI operations — creation, update, deletion — are performed through JSI, ensuring minimal latency.
// Fabric C++ rendering pipeline via JSI
void mountShadowNode(
jsi::Runtime& runtime,
const ShadowNode::Shared& shadowNode,
const ShadowNode::SharedList& children
) {
auto props = shadowNode->getProps();
auto state = shadowNode->getState();
// Synchronous prop transfer via JSI
jsiValue.asObject(runtime)
.getProperty(runtime, "style")
.asObject(runtime);
// Layout calculation through Yoga directly
auto layoutMetrics =
YogaLayoutableShadowNode::layout(children);
// Apply mutations to native UI
UIManager::synchronouslyUpdateViewOnUIThread(
shadowNode->getTag(), layoutMetrics
);
}
The key advantage is synchronous update. In the old architecture, the UI was updated through an async queue: React sent a command through the Bridge, Shadow Thread processed the layout, Native Thread rendered. In Fabric, all steps are executed sequentially in a single pass. This eliminates race conditions and ensures the UI matches the current application state.
Migrating to Fabric does not require rewriting React components — all existing React Native components continue to work. However, libraries with native code (Native Module, custom ViewManager) may require updates. Meta recommends checking the compatibility of each library before enabling the new architecture.
To enable Fabric in a React Native 0.76+ project, set the newArchEnabled: true flag in react-native.config.js. Fabric will enable automatically along with Turbo Module. If issues arise, Fabric can be disabled by reverting to the old renderer without changing application code — both architectures are supported in parallel.
// package.json — check Fabric-compatible libraries
"react-native": "0.76.6",
"react-native-safe-area-context": "^5.0.0",
"react-native-screens": "^4.0.0",
"react-native-reanimated": "^3.16.0",
"react-native-gesture-handler": "^2.21.0"
When migrating, it’s important to update all native libraries to versions compatible with Fabric. Major libraries such as react-native-reanimated and react-native-gesture-handler already support the new architecture. For libraries that have not yet been updated, Fabric provides a compatibility mechanism — if a library does not support Fabric, the renderer automatically falls back to the old one for that library.
Frequently Asked Questions
Yes, starting from Expo SDK 52 the new architecture is enabled by default. Fabric and Turbo Modules are available in managed workflow without additional setup.
Fabric significantly improves animations through synchronous rendering. Animations on the JS thread no longer compete with Bridge message processing, eliminating jank and FPS drops.
No, all standard React Native components work with Fabric without changes. Only custom ViewManager components require updating to support the new architecture.
Set newArchEnabled: false in react-native.config.js and rebuild the app. All modules and components will continue to work without changes — Fabric and the old renderer are fully interchangeable.
Bridgeless mode is a Fabric operating mode in which the Bridge is completely disabled. All communication goes through JSI only, providing maximum performance. Available in React Native 0.76+.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also