React Native Renderer (Fabric)
Fabric is the React Native renderer that connects React’s reconciler to native view nodes. Its host config creates native nodes, builds child sets, clones persisted instances, and hands completed children to the native UI manager rather than constructing browser DOM nodes.
It exists so React’s rendering model can remain shared while the host-specific work is implemented for React Native. The reconciler selects this implementation through the Fabric fork, which re-exports ReactFiberConfigFabric as the reconciler host config.
Sources: packages/react-native-renderer/src/ReactFiberConfigFabric.js:184-227, packages/react-native-renderer/src/ReactFiberConfigFabric.js:562-568, packages/react-native-renderer/src/ReactFiberConfigFabric.js:588-593, packages/react-reconciler/src/forks/ReactFiberConfig.fabric.js:1-11
Core concepts
Host config
A host config is the renderer-specific implementation that tells the reconciler how to create, represent, update, and commit host objects. Fabric identifies itself as react-native-renderer and supplies native-specific host operations.
Sources: packages/react-native-renderer/src/ReactFiberConfigFabric.js:80, packages/react-native-renderer/src/ReactFiberConfigFabric.js:184-227, packages/react-native-renderer/src/ReactFiberConfigFabric.js:588-593
Native instance
A native instance is Fabric’s internal wrapper around a native node and its canonical metadata. createInstance stores the native tag, view configuration, current props, internal handle, and lazily created public instance in canonical.
Sources: packages/react-native-renderer/src/ReactFiberConfigFabric.js:184-227
Public instance
A public instance is the object exposed to React Native integrations from a host fiber. Fabric creates it from the canonical native tag and view configuration, while root containers return their stored public root instance.
Sources: packages/react-native-renderer/src/ReactFiberConfigFabric.js:300-322
Persistence
Persistence means updates produce cloned native nodes and child sets, then replace the container’s children as a completed set. Fabric advertises this mode with supportsPersistence.
Sources: packages/react-native-renderer/src/ReactFiberConfigFabric.js:481, packages/react-native-renderer/src/ReactFiberConfigFabric.js:483-536, packages/react-native-renderer/src/ReactFiberConfigFabric.js:562-568, packages/react-native-renderer/src/ReactFiberConfigFabric.js:588-593
How a Fabric root gets scheduled
The public render entry point looks up a root by containerTag; if none exists, it creates a public root instance, builds a reconciler container, stores it in roots, and calls updateContainer. This lets repeated renders reuse the same root while the reconciler owns the update flow.
Evidence
- render-entrypackages/react-native-renderer/src/ReactFabric.js:108
- root-storepackages/react-native-renderer/src/ReactFabric.js:214
- container-factorypackages/react-native-renderer/src/ReactFabric.js:108
- container-updatepackages/react-native-renderer/src/ReactFabric.js:108
- public-rootpackages/react-native-renderer/src/ReactFabric.js:108
The call order matters because root creation is conditional: createContainer and roots.set occur only when the tag has no existing root, while updateContainer runs after either branch.
Unmounting follows the same root ownership model. stopSurface gets the root, submits null through updateContainer, clears the public instance in the completion callback, and deletes the root from roots; unmountComponentAtNode delegates to it.
Sources: packages/react-native-renderer/src/ReactFabric.js:108-174, packages/react-native-renderer/src/ReactFabric.js:177-179, packages/react-native-renderer/src/ReactFabric.js:181-192
How a fiber becomes a native view
For a host component, createInstance allocates a React Native tag, resolves the view configuration, derives an attribute payload, and calls createNode with the tag, native view class, root tag, props, and internal instance handle. The returned Instance keeps both the native node and the canonical mapping metadata.
This is the key difference from a DOM-oriented host implementation: Fabric’s host object is explicitly backed by a native tag and a native view configuration. The fiber does not itself become the public native object; its stateNode leads to the Fabric instance, which leads to the canonical native metadata and, when needed, the public instance.
Text uses a separate native representation. createTextInstance allocates another tag and calls createNode with the RCTRawText view name and {text: text} props. In development, Fabric also checks that raw text is rendered inside an allowed parent-text context.
Fabric’s component-tree helpers expose the mapping in both directions. getInstanceFromNode returns canonical.internalInstanceHandle when present, getNodeFromInstance converts a fiber’s stateNode through getPublicInstance, and getFiberCurrentPropsFromNode reads canonical.currentProps.
For public access, getPublicInstanceFromInternalInstanceHandle reads stateNode, returns null for an unmounted fiber, creates a public text instance for HostText, and otherwise calls getPublicInstance. This preserves a single conversion path for host fibers while handling text separately.
Sources: packages/react-native-renderer/src/ReactFiberConfigFabric.js:184-227, packages/react-native-renderer/src/ReactFiberConfigFabric.js:300-322, packages/react-native-renderer/src/ReactFiberConfigFabric.js:229-254, packages/react-native-renderer/src/ReactFabricComponentTree.js:22-34, packages/react-native-renderer/src/ReactFabricComponentTree.js:36-44, packages/react-native-renderer/src/ReactFabricComponentTree.js:46-48, packages/react-native-renderer/src/ReactFiberConfigFabric.js:336-354
How Fabric commits native changes
Fabric appends initial children by passing the underlying node objects to appendChildNode. It does not perform a browser-style initial-finalization action: finalizeInitialChildren returns false.
Updates use persistence rather than mutating the original instance in place. cloneInstance diffs old and new props, updates canonical.currentProps, and chooses among cloning with new props, new children, or both. If there is no payload and children are retained, it returns the existing instance.
The reconciler builds a container child set with createContainerChildSet, appends child nodes into that set, and then calls replaceContainerChildren. The final host operation is completeRoot(container.containerTag, newChildren), which hands the completed native child set to the platform boundary.
Evidence
- host-instancepackages/react-native-renderer/src/ReactFiberConfigFabric.js:184
- native-nodepackages/react-native-renderer/src/ReactFiberConfigFabric.js:184
- persisted-clonepackages/react-native-renderer/src/ReactFiberConfigFabric.js:483
- child-setpackages/react-native-renderer/src/ReactFiberConfigFabric.js:562
- root-replacerpackages/react-native-renderer/src/ReactFiberConfigFabric.js:588
- fabric-uipackages/react-native-renderer/src/ReactFiberConfigFabric.js:588
Several commit hooks are intentionally no-ops in this host config: prepareForCommit, resetAfterCommit, portal preparation, deleted-instance detachment, and post-paint callback requests. Fabric also reports no commit suspension in its suspension hooks, while preloadInstance returns true.
Fabric supplies scheduling details without changing the reconciler’s update model. It stores the current event priority, resolves native Fabric event priorities to reconciler event priorities, tracks the scheduler event, and resolves event type and timestamp from global.event.
Sources: packages/react-native-renderer/src/ReactFiberConfigFabric.js:175-180, packages/react-native-renderer/src/ReactFiberConfigFabric.js:256-263, packages/react-native-renderer/src/ReactFiberConfigFabric.js:483-536, packages/react-native-renderer/src/ReactFiberConfigFabric.js:562-568, packages/react-native-renderer/src/ReactFiberConfigFabric.js:588-593, packages/react-native-renderer/src/ReactFiberConfigFabric.js:364-367, packages/react-native-renderer/src/ReactFiberConfigFabric.js:369-371, packages/react-native-renderer/src/ReactFiberConfigFabric.js:607-609, packages/react-native-renderer/src/ReactFiberConfigFabric.js:611-613, packages/react-native-renderer/src/ReactFiberConfigFabric.js:615-617, packages/react-native-renderer/src/ReactFiberConfigFabric.js:619-621, packages/react-native-renderer/src/ReactFiberConfigFabric.js:638-644, packages/react-native-renderer/src/ReactFiberConfigFabric.js:384-386, packages/react-native-renderer/src/ReactFiberConfigFabric.js:392-417, packages/react-native-renderer/src/ReactFiberConfigFabric.js:420-422, packages/react-native-renderer/src/ReactFiberConfigFabric.js:453-456, packages/react-native-renderer/src/ReactFiberConfigFabric.js:458-461
How it connects
The reconciler consumes Fabric through packages/react-reconciler/src/forks/ReactFiberConfig.fabric.js, which exports the Fabric host config and the plain client console config. This is the host boundary that lets reconciler algorithms remain separate from native node creation and commitment.
The renderer’s public entry points connect container tags to React roots, portals, public instances, and native error handling. createPortal delegates to createPortalImpl, while native error callbacks route through ReactFiberErrorDialog.showErrorDialog before default logging unless the dialog suppresses it.
DevTools and inspection use the same canonical mapping. Fabric exposes extraDevToolsConfig, and native inspection can read canonical.nativeTag from an internal instance handle when measuring a selected view.
For the broader runtime picture, start with React Overview, then see Fiber Architecture for the fiber and stateNode model, Render Phase and Commit Phase for reconciler execution, and ReactDOM Host Config for the web renderer’s host boundary.
Sources: packages/react-reconciler/src/forks/ReactFiberConfig.fabric.js:1-11, packages/react-native-renderer/src/ReactFabric.js:194-200, packages/react-native-renderer/src/ReactFabric.js:60-79, packages/react-native-renderer/src/ReactFiberConfigFabric.js:81-84, packages/react-native-renderer/src/ReactNativeFiberInspector.js:172-183
Key takeaways
- Fabric implements the host-specific side of rendering: native tags, view configurations, native nodes, public instances, and native root replacement.
- A host fiber reaches a native view through
stateNode,canonical, and the native tag stored in canonical.nativeTag. - Updates are persistent: Fabric clones instances, builds child sets, and replaces completed root children.
- Root scheduling, update submission, fiber construction, lanes, reconciliation, and commit orchestration remain responsibilities of the shared reconciler selected through the host-config fork.
Sources: packages/react-native-renderer/src/ReactFiberConfigFabric.js:184-227, packages/react-native-renderer/src/ReactFiberConfigFabric.js:300-322, packages/react-native-renderer/src/ReactFiberConfigFabric.js:588-593, packages/react-native-renderer/src/ReactFiberConfigFabric.js:336-354, packages/react-native-renderer/src/ReactFiberConfigFabric.js:481, packages/react-native-renderer/src/ReactFiberConfigFabric.js:483-536, packages/react-native-renderer/src/ReactFiberConfigFabric.js:562-568, packages/react-reconciler/src/forks/ReactFiberConfig.fabric.js:1-11, packages/react-native-renderer/src/ReactFabric.js:108-174