This page provides an overview of how React targets multiple host environments through a renderer architecture centered on the host configuration abstraction. It covers the reconciler's renderer contract, the purpose of each renderer package in the monorepo, and the structural patterns common to all implementations.
For the DOM implementation in detail, see React DOM Implementation. For the DOM event system, see React DOM Event System. For React Native renderers, see React Native Renderers. For hydration, see Hydration System. For view transitions and gesture scheduling, see View Transitions and Gesture Scheduling. For the host configuration abstraction itself, see Host Configuration Abstraction.
React separates rendering logic into two layers:
react-reconciler) — handles the Fiber tree, diffing, scheduling, and work loop. It is host-agnostic.ReactFiberConfig, which the build system substitutes per platform.Each renderer package provides its own implementation of the host config contract and wires it into the reconciler. The result is a complete, standalone renderer package (e.g. react-dom, react-native-renderer, react-test-renderer).
Renderer Package Overview
| Package | Config File | Render Target | Mutation Model |
|---|---|---|---|
react-dom | ReactFiberConfigDOM.js | Browser DOM | Mutation |
react-native-renderer (Paper) | ReactFiberConfigNative.js | RN UIManager (legacy) | Mutation |
react-native-renderer (Fabric) | ReactFiberConfigFabric.js | nativeFabricUIManager | Persistence |
react-test-renderer | ReactFiberConfigTestHost.js | In-memory JS tree | Mutation |
react-art | ReactFiberConfigART.js | ART canvas/SVG | Mutation |
react-noop-renderer | createReactNoop.js | In-memory (testing) | Mutation or Persistence |
Sources: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js1-152 packages/react-native-renderer/src/ReactFiberConfigFabric.js1-90 packages/react-native-renderer/src/ReactFiberConfigNative.js1-60 packages/react-test-renderer/src/ReactFiberConfigTestHost.js1-65 packages/react-art/src/ReactFiberConfigART.js1-35 packages/react-noop-renderer/src/createReactNoop.js1-50
The host config is the interface between the reconciler and any platform. During the build, the file packages/react-reconciler/src/ReactFiberConfig.js is forked to the appropriate platform implementation. For third-party renderers consuming the public react-reconciler npm package, the shim ReactFiberConfig.custom.js proxies every export through a $$$config argument passed at instantiation time.
Host Config Method Categories
| Category | Representative Methods | Notes |
|---|---|---|
| Instance creation | createInstance, createTextInstance, appendInitialChild | Required for all renderers |
| Context propagation | getRootHostContext, getChildHostContext | Tracks namespace / text-parent state |
| Commit lifecycle | prepareForCommit, resetAfterCommit, commitMount, commitUpdate | Called around mutation phase |
| Mutation (optional) | appendChild, insertBefore, removeChild, commitTextUpdate | Set supportsMutation = true |
| Persistence (optional) | cloneInstance, createContainerChildSet, replaceContainerChildren | Set supportsPersistence = true |
| Hydration (optional) | supportsHydration = true | DOM-only currently |
| Microtasks (optional) | scheduleMicrotask, supportsMicrotasks | DOM and noop support this |
| Resources / Singletons | supportsResources, supportsSingletons | DOM <head> hoisting |
| View transitions | applyViewTransitionName, startViewTransition, measureInstance | DOM mutation renderer only |
| Suspend-on-commit | maySuspendCommit, preloadInstance, startSuspendingCommit, waitForCommitToBeReady | DOM and noop |
Sources: packages/react-reconciler/src/forks/ReactFiberConfig.custom.js1-200
Host Config Shim for Third-Party Renderers
ReactFiberConfig.custom.js wraps each export as:
export const createInstance = $$$config.createInstance;
The reconciler bundle for npm is wrapped in a function module.exports = function ($$$config) { ... }, so $$$config refers to the object passed by the renderer author.
Sources: packages/react-reconciler/src/forks/ReactFiberConfig.custom.js10-30
Platform Renderer Structure
Sources: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js1-50 packages/react-native-renderer/src/ReactFiberConfigFabric.js1-90 packages/react-native-renderer/src/ReactFiberConfigNative.js1-60 packages/react-test-renderer/src/ReactFiberConfigTestHost.js1-65 packages/react-art/src/ReactFiberConfigART.js1-35 packages/react-noop-renderer/src/createReactNoop.js1-50 packages/react-reconciler/src/forks/ReactFiberConfig.custom.js1-60
Each host config file exports a set of opaque type aliases that the reconciler works with. The concrete types differ per platform.
Type mapping across platforms
| Type alias | DOM | Fabric | Paper (Native) | Test Renderer |
|---|---|---|---|---|
Container | Element | Document | DocumentFragment | {containerTag, publicInstance} | {containerTag, publicInstance} | {children, createNodeMock, tag} |
Instance | Element | {node, canonical} | ReactNativeFiberHostComponent | {type, props, children, tag: 'INSTANCE'} |
TextInstance | Text | {node, publicInstance?} | number (native tag) | {text, isHidden, tag: 'TEXT'} |
PublicInstance | Element | Text | ReactNativePublicInstance | Instance (same) | Instance | TextInstance |
UpdatePayload | Array<mixed> | Object (attribute diff) | Object | Object |
ChildSet | void (unused) | Object | Array<Node> | void | void |
Sources: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js154-260 packages/react-native-renderer/src/ReactFiberConfigFabric.js96-155 packages/react-native-renderer/src/ReactFiberConfigNative.js59-90 packages/react-test-renderer/src/ReactFiberConfigTestHost.js26-57
The DOM renderer is distributed through two packages:
react-dom — public entry point, exports createRoot, hydrateRoot, and legacy render.react-dom-bindings — implementation detail containing ReactFiberConfigDOM.js, ReactDOMComponent.js, the event system, and form element modules.Key responsibilities of ReactFiberConfigDOM.js:
createInstance — calls document.createElement or createElementNS (for SVG/MathML) and stores the fiber back-link via precacheFiberNode.finalizeInitialChildren — calls setInitialProperties to apply all DOM props and returns true for elements that need commitMount (e.g., autoFocus, img).commitUpdate — calls updateProperties to diff and apply changed props, then updateFiberProps.prepareForCommit / resetAfterCommit — save and restore selection state, disable/re-enable event emitter during mutation.supportsMutation = true, supportsPersistence = false, supportsHydration = true.queueMicrotask or Promise.resolve.<head>, <html>, <body> are treated specially).<link>, <style>, <script> hoisting (Float).The HostContext in the DOM renderer tracks the XML namespace (None / SVG / Math) and, in dev mode, the ancestor tag stack for validateDOMNesting.
Sources: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js303-670 packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js812-960
DOM Instance Creation Flow
Sources: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js485-666
There are two React Native renderers, targeting different architectural layers:
File: packages/react-native-renderer/src/ReactFiberConfigNative.js
UIManager (the legacy bridge) to create and update native views imperatively.Instance is ReactNativeFiberHostComponent, a JS class that wraps the native tag (_nativeTag) and view config.TextInstance is a plain number (the native tag).supportsMutation = true).createInstance calls UIManager.createView(tag, viewName, rootTag, updatePayload).finalizeInitialChildren calls UIManager.setChildren to attach initial children.commitUpdate calls UIManager.updateView.Sources: packages/react-native-renderer/src/ReactFiberConfigNative.js60-262
File: packages/react-native-renderer/src/ReactFiberConfigFabric.js
nativeFabricUIManager — a JSI-based interface that operates on shadow nodes.Instance is {node: Node, canonical: {...}}. The node is a Fabric shadow node.supportsPersistence = true). Nodes are immutable; updates clone them.createInstance calls nativeFabricUIManager.createNode(tag, viewName, rootTag, updatePayload, handle).cloneInstance calls cloneNodeWithNewProps or cloneNodeWithNewChildren depending on what changed.completeRoot atomically commits the entire new child set to the native layer.fabricGetCurrentEventPriority from the Fabric bridge.isPrimaryRenderer = false because Paper may coexist in the same app.Sources: packages/react-native-renderer/src/ReactFiberConfigFabric.js46-560
Paper vs. Fabric Comparison
Sources: packages/react-native-renderer/src/ReactFiberConfigNative.js130-200 packages/react-native-renderer/src/ReactFiberConfigFabric.js179-260
File: packages/react-test-renderer/src/ReactFiberConfigTestHost.js
Instance and TextInstance objects.Instance = {type, props, isHidden, children, internalInstanceHandle, rootContainerInstance, tag: 'INSTANCE'}.TextInstance = {text, isHidden, tag: 'TEXT'}.getPublicInstance calls createNodeMock from the container, which allows users to return custom mock objects for refs.HostContext is always NO_CONTEXT (a frozen empty object).Used for unit tests where DOM is not available or undesirable.
Sources: packages/react-test-renderer/src/ReactFiberConfigTestHost.js26-205
File: packages/react-noop-renderer/src/createReactNoop.js
The noop renderer is created by calling createReactNoop(reconciler, useMutation). It is used extensively in reconciler-level tests (react-reconciler/src/__tests__/).
Instance = {id, type, children, parent, text, prop, hidden, context}.suspensey-thing host component type used to test commit-phase Suspense.UPPERCASE_CONTEXT is a host context used to test context-dependent text rendering.getPublicInstance returns the instance itself.flushSync, render, act, getChildrenAsJSX, toMatchRenderedOutput.Sources: packages/react-noop-renderer/src/createReactNoop.js44-110 packages/react-noop-renderer/src/createReactNoop.js375-988
File: packages/react-art/src/ReactFiberConfigART.js
Instance wraps ART Node and Group objects.Sources: packages/react-art/src/ReactFiberConfigART.js1-50
Renderers declare which optional capabilities they support via boolean exports. The reconciler branches on these at runtime.
| Flag | DOM | Fabric | Paper | Test | Noop |
|---|---|---|---|---|---|
supportsMutation | ✓ | — | ✓ | ✓ | configurable |
supportsPersistence | — | ✓ | — | — | configurable |
supportsHydration | ✓ | — | — | — | — |
supportsMicrotasks | ✓ | — | — | — | ✓ |
supportsResources | ✓ | — | — | — | — |
supportsSingletons | ✓ | — | — | — | — |
isPrimaryRenderer | true | false | true | true | true |
warnsIfNotActing | true | false | — | — | true |
For each capability set to false or absent, the reconciler imports a no-op fallback module. For example, Paper imports ReactFiberConfigWithNoHydration, ReactFiberConfigWithNoPersistence, and ReactFiberConfigWithNoMicrotasks.
Sources: packages/react-native-renderer/src/ReactFiberConfigNative.js115-121 packages/react-native-renderer/src/ReactFiberConfigFabric.js163-169 packages/react-test-renderer/src/ReactFiberConfigTestHost.js59-65 packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js772-828
Every renderer must implement getRootHostContext and getChildHostContext. These functions form a stack that travels down the fiber tree during beginWork, giving each host instance knowledge of its rendering environment.
| Renderer | Context contents | Purpose |
|---|---|---|
| DOM | HostContextNamespace (0/1/2) + dev ancestorInfo | Track SVG/MathML namespace; validate nesting |
| Fabric | {isInAParentText: boolean} | Detect raw text outside <Text> |
| Paper | {isInAParentText: boolean} | Same as Fabric |
| Test | NO_CONTEXT (empty object) | No special needs |
| Noop | NO_CONTEXT or UPPERCASE_CONTEXT | Test context propagation |
Sources: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js303-410 packages/react-native-renderer/src/ReactFiberConfigFabric.js262-295 packages/react-native-renderer/src/ReactFiberConfigNative.js263-288 packages/react-test-renderer/src/ReactFiberConfigTestHost.js136-147
Renderers that support view transitions (currently only the DOM mutation renderer) must implement an additional set of hooks. These are called by ReactFiberCommitViewTransitions.js and ReactFiberApplyGesture.js during the commit phase.
Key view-transition hooks in ReactFiberConfigDOM.js:
applyViewTransitionName / restoreViewTransitionName / cancelViewTransitionNamemeasureInstance / measureClonedInstance / wasInstanceInViewport / hasInstanceChangedstartViewTransition / stopViewTransition / addViewTransitionFinishedListenerstartGestureTransition / getCurrentGestureOffsetcloneRootViewTransitionContainer / removeRootViewTransitionCloneNoop renderer implements stubs that immediately invoke callbacks without any animation.
Sources: packages/react-noop-renderer/src/createReactNoop.js798-908 packages/react-reconciler/src/ReactFiberCommitViewTransitions.js1-70 packages/react-reconciler/src/ReactFiberApplyGesture.js1-100
Refresh this wiki