Fabric is React Native’s reimagined rendering system, built from the ground up to leverage JSI and support modern React features like Concurrent React. It replaces the legacy UIManager with a type-safe, performant renderer that can execute layout synchronously on any thread.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/facebook/react-native/llms.txt
Use this file to discover all available pages before exploring further.
Core Concepts
Shadow Tree
The shadow tree is an immutable tree of shadow nodes that represents the structure and properties of your UI. This tree exists in C++ and serves as the single source of truth for the UI state.Shadow Nodes
Shadow nodes are immutable objects defined inReactCommon/react/renderer/core/ShadowNode.h:
- Immutability - Once created, shadow nodes never change; mutations create new nodes
- Structural sharing - Unchanged subtrees are shared between versions
- Layout cache - Yoga layout results are cached on nodes
- Type safety - Strongly typed props specific to each component type
Shadow Node Family
Each shadow node belongs to a “family” that identifies the component instance across revisions:- Maintains component identity through re-renders
- Enables React’s reconciliation across shadow tree updates
- Links shadow nodes to their JavaScript component instances
Component Descriptors
Component descriptors are factories for creating and cloning shadow nodes of specific types. They’re defined inReactCommon/react/renderer/core/ComponentDescriptor.h.
Each native component (View, Text, Image, etc.) has a descriptor that:
- Creates shadow nodes with the correct concrete type
- Parses and creates typed Props objects
- Manages component-specific State
- Handles event emission
ComponentDescriptorRegistry maintains all available descriptors and looks them up by component name.
Props
Props are immutable, type-safe property bags that configure shadow nodes:- Strongly typed - Each component has its own Props struct
- Codegen-generated - For custom components, Codegen creates Props definitions
- Efficient - Only changed props are serialized across the JSI boundary
- Platform-specific - Can include platform-specific properties
State
State represents native-managed state for a component, separate from React state:- Image loading state - Track image load progress
- Text layout - Cache measured text dimensions
- Scroll position - Native scroll state
- Native animations - Animation progress
Event Emitters
Event emitters handle communication from native back to JavaScript:- Discrete - High priority events like press, focus (sync to next frame)
- Continuous - Scroll, drag, mouse move (batched and throttled)
- AsynchronousBatched - Default, batched with event loop
Rendering Pipeline
Fabric’s rendering pipeline consists of three main phases:1. Render Phase
Executes on the JavaScript thread:UIManagerBinding (exposed to JavaScript via JSI):
createNode()- Create new shadow nodescloneNode()- Clone nodes with updated propsappendChild()- Build tree structurecompleteRoot()- Commit the tree
2. Commit Phase
Executes on background thread, coordinated by theShadowTree:
Layout Calculation
Yoga (Facebook’s flexbox implementation) computes layout:- Runs on any thread (typically background)
- Cached results reused for unchanged subtrees
- Supports measure functions for text and images
- Returns pixel-perfect layouts
Commit Hooks
Commit hooks allow intercepting the commit process:- Pre-commit hooks - Modify tree before layout (e.g., Animation Backend)
- Post-commit hooks - Process results after layout
ReactCommon/react/renderer/uimanager/UIManagerCommitHook.h.
Diffing
TheDifferentiator compares old and new shadow trees:
- Generates minimal set of mutations
- Handles insertions, deletions, updates, reordering
- Optimized for common patterns (append, prepend)
- Output is a
MountingTransaction
3. Mount Phase
Executes on the UI thread:MountingCoordinator delivers transactions to the platform:
- iOS -
RCTMountingManagerapplies mutations to UIViews - Android -
MountingManagerapplies mutations to Android Views
UIManager
TheUIManager orchestrates the entire rendering system. Defined in ReactCommon/react/renderer/uimanager/UIManager.h:
- Manages multiple shadow trees (one per React root/surface)
- Coordinates commits across shadow trees
- Applies mutations via delegates
- Integrates with animation backend
- Manages component descriptor registry
Surface Management
A “surface” is a React root rendered into a native view hierarchy. Each surface:- Has its own
ShadowTree - Has a unique
SurfaceId - Can be mounted/unmounted independently
- Supports different display modes (visible, suspended, hidden)
- Native navigation with React screens
- Modal overlays
- Native UI with embedded React content
Synchronous Layout
One of Fabric’s major improvements is synchronous layout measurement:- Layout is calculated in C++, accessible to JavaScript via JSI
- No asynchronous bridge round-trip
- Cached results returned instantly
- Positioning tooltips and popovers
- Measuring text before render
- Implementing custom layouts
- Avoiding layout flicker
Runtime Shadow Node Reference Updates (RSNRU)
RSNRU is an optimization that keeps React’s references to shadow nodes fresh. FromReactCommon/react/renderer/core/__docs__/RSNRU.md:
RSNRU ensures React always holds references to the latest shadow node revisions, even after they’re cloned internally by Fabric operations like layout or state updates.
- Better layout cache hits - React reuses computed layouts
- Fresh native state - State updates visible to React
- Fewer re-layouts - Avoids redundant layout calculations
- Shadow nodes can be cloned by native operations (layout, state updates)
- When cloned, RSNRU updates wrapper objects held by React
- React’s next render uses the latest revision
- Layout cache and state remain fresh
Concurrent React Support
Fabric is designed for Concurrent React features:Priority-Based Rendering
Different updates have different priorities:- Synchronous - User input, critical updates
- Default - Most state updates
- Idle - Analytics, logging
RuntimeScheduler processes tasks by priority:
Interruptible Rendering
Low-priority work can be interrupted:- Start rendering a low-priority update
- High-priority event occurs (user input)
- Pause low-priority work
- Process high-priority update immediately
- Resume or discard low-priority work
Time Slicing
Long renders are broken into chunks:- Render for 5ms
- Yield to handle input
- Resume rendering
- Prevents blocking user interactions
Platform Integration
iOS (Objective-C++)
RCTSurfacePresenter- Manages surfaces and mountingRCTMountingManager- Applies mutations to UIViewsRCTScheduler- Coordinates React rendersRCTComponentViewRegistry- Maps tags to UIViews
Android (JNI/C++)
FabricUIManager- Java interface to C++ UIManagerMountingManager- Applies mutations to Android ViewsReactInstanceManager- Manages React instancesViewManagerRegistry- Component view managers
Performance Characteristics
Fabric delivers significant performance improvements:Startup Performance
- Faster initialization - C++ components initialized once
- Lazy mounting - Views created only when needed
- Shared layout engine - Yoga shared across components
Runtime Performance
- Synchronous operations - No bridge serialization delays
- Efficient diffing - Minimal mutation sets
- Layout cache - Computed layouts reused extensively
- Priority scheduling - Important updates processed first
Memory Usage
- Structural sharing - Unchanged subtrees shared
- Copy-on-write - Only changed nodes allocated
- Smart pointers - Automatic memory management
Debugging Fabric
Enable Fabric Logs
iOS:Inspector Integration
Fabric integrates with React DevTools:- Inspect shadow tree structure
- View props and state
- Measure layout
- Track renders and commits
Performance Profiling
Use native profilers:- Xcode Instruments - Time Profiler, Allocations
- Android Studio Profiler - CPU, Memory, Frame rendering
- React DevTools Profiler - Component render times
Migration from Legacy Renderer
Enabling Fabric
React Native 0.68+ uses Fabric by default. To ensure it’s enabled: iOS Podfile:Component Compatibility
Most built-in components work with Fabric. Custom native components need:- Component descriptors - Define in C++
- Codegen specs - TypeScript/Flow component spec
- View managers - Update for Fabric APIs
Breaking Changes
- setNativeProps removed - Use state updates instead
- findNodeHandle deprecated - Use refs directly
- UIManager methods changed - Some APIs removed or modified
- Timing differences - Synchronous operations may change timing
Best Practices
Optimize Re-renders
Minimize shadow tree churn:Use React.memo
Prevent unnecessary component updates:Batch State Updates
Multiple updates in same task are batched:Avoid Layout Thrashing
Don’t interleave layout reads and writes:Further Reading
Threading Model
Understand Fabric’s threading architecture
TurboModules
Learn about native modules in new architecture
JavaScript Interface
JSI fundamentals powering Fabric
Codegen
Generate component specs