ReactDOM Host Config
The ReactDOM host config is the DOM-specific boundary between the reconciler and the browser. The reconciler package is wrapped as a factory: consumers pass a hostConfig object and receive the reconciler API, while ReactDOM supplies functions that create, update, hydrate, and remove DOM-backed host instances.
This boundary exists so reconciliation can describe work without knowing whether the result is an HTML element, a native view, or another host object. The custom fork explicitly adapts the public argument-based API to the reconciler’s module-shaped internal view.
Sources: packages/react-reconciler/index.js:10-17, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:534-664, packages/react-reconciler/src/forks/ReactFiberConfig.custom.js:10-23
Core concepts
Host config
A host config is the renderer-provided set of operations that lets the reconciler manipulate a host tree. The repository exposes that contract as HostConfig and accepts it through hostConfig.
Sources: packages/react-reconciler/index.js:10-17
Host context
Host context is renderer state carried down the host tree; in ReactDOM it tracks namespaces such as HTML, SVG, and MathML, plus development-only ancestor information.
Sources: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:298, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:299, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:314-367
Host instance
A host instance is the concrete DOM object representing a rendered element. createInstance creates an element from its type, props, root container, and host context, while createTextInstance creates a DOM text node.
Sources: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:534-664, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:757-779
Container
A container is the DOM entry point into which the reconciler inserts host instances. getOwnerDocumentFromRootContainer accepts an Element, Document, or DocumentFragment and resolves its owner document.
Sources: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:306-312
Hydration
Hydration is the matching and repair path that reuses existing DOM instead of assuming every host node is new. ReactDOM identifies hydratable elements, text nodes, comment boundaries, and form-state markers.
The main structure is a renderer-independent reconciler handing host work to DOM-specific creation and mutation operations.
Evidence
- host-contextpackages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:314
- instance-creationpackages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:534
- owner-documentpackages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:306
- owner-documentpackages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:534
- dom-instancepackages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:534
- host-treepackages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:695
Sources: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4078-4225, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4227-4254, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4400-4423, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:534-664, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:999-1012, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:1082-1133
How host context selects the DOM namespace
The root context starts from the container’s node type. A document or document fragment derives its namespace from the document element when one exists; an element container derives it from its tag and namespace URI. Development builds also attach ancestor information for DOM-nesting validation.
Child context then carries the namespace downward, enters SVG or MathML at the corresponding tag, and leaves SVG when it encounters foreignObject. The exported getChildHostContext preserves that namespace logic and adds development ancestor tracking when enabled.
When createInstance receives this context, it validates nesting in development and chooses the correct DOM constructor: createElementNS for SVG and MathML, or createElement for ordinary HTML. It also has special construction paths for script, select, and customized elements.
The creation call order is therefore context first, document resolution second, and DOM construction third.
Evidence
- root-contextpackages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:314
- instance-builderpackages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:534
- owner-documentpackages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:306
- owner-documentpackages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:534
- browser-documentpackages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:534
- dom-instancepackages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:534
Sources: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:314-367, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:380-401, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:403-418, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:534-664
How the host tree is created and committed
Initial construction is split between creating an individual node, assembling disconnected children, and finalizing properties. appendInitialChild uses appendChild because initial children are appended while disconnected. finalizeInitialChildren applies initial properties and reports a commit-time update for autofocus controls and images.
Text has its own path. shouldSetTextContent identifies elements whose children can be represented directly as text content, including textarea, noscript, primitive children, and dangerouslySetInnerHTML; otherwise createTextInstance creates a separate text node.
Commit-time updates are similarly divided. commitUpdate diffs properties and refreshes the stored props handle, resetTextContent clears element text, and commitTextUpdate assigns the new text node value.
Structural operations handle both ordinary parents and containers. appendChild, insertBefore, and removeChild mutate an element parent; their container counterparts select the document body, comment parent, HTML body, or supplied container before performing the mutation.
ReactDOM also brackets a commit with browser-specific preparation. prepareForCommit disables event handling and captures selection information, while resetAfterCommit restores selection and the previous event state. If an active instance is detached, beforeActiveInstanceBlur and afterActiveInstanceBlur temporarily re-enable events to dispatch the corresponding blur work.
| Host-config area | DOM responsibility | Representative operations |
|---|---|---|
| Context | Track namespace and nesting state | getRootHostContext, getChildHostContext |
| Creation | Make elements and text nodes | createInstance, createTextInstance |
| Initial assembly | Build disconnected subtrees | appendInitialChild, finalizeInitialChildren |
| Mutation | Insert, move, remove, and update nodes | appendChild, insertBefore, removeChild, commitUpdate |
| Text | Decide and apply text representation | shouldSetTextContent, resetTextContent, commitTextUpdate |
| Commit coordination | Preserve browser event and selection state | prepareForCommit, resetAfterCommit |
These operations show the practical surface a renderer must cover for ordinary host-tree creation and commit behavior.
Sources: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:695-701, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:703-721, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:744-755, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:757-779, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:999-1012, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:1014-1016, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:1018-1024, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:1032-1042, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:1135-1146, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:1213-1218, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:1082-1133, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:424-436, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:457-462, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:438-447, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:449-455, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:314-367, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:403-418, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:534-664
How hydration and optional host features extend the contract
Hydration starts by skipping nodes that are not hydratable. getNextHydratable accepts elements and text nodes, recognizes specific comment markers for Suspense, Activity, and form state, and stops at boundary end markers. getNextHydratableSibling applies that scan to a node’s following siblings.
Matching then separates element, text, boundary, and form-state cases. canHydrateInstance compares element names and handles hidden inputs and hoistable resources; canHydrateTextInstance searches for a text node; and the Activity and Suspense matchers require the appropriate comment marker. Form markers are recognized by canHydrateFormStateMarker, with isFormStateMarkerMatching distinguishing matching from non-matching state.
Hydration boundaries are treated as nested regions. getNextHydratableInstanceAfterHydrationBoundary tracks nested start and end markers before resuming after the outer boundary. If a boundary must be discarded, clearHydrationBoundary removes its nodes while tracking nesting depth and retries blocked event replay.
The host config also includes browser capabilities beyond basic mutation. ReactDOM exposes event preparation for portals, singleton scope detection for head, and resource-related operations such as getHoistableRoot. View transitions add measurement, mutation, layout, and error callbacks around ownerDocument.startViewTransition. A renderer that does not target the DOM would replace these operations with equivalents for its own host environment, or omit capabilities it does not support.
Sources: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4431-4457, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4459-4463, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4078-4225, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4227-4254, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4281-4296, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4298-4313, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4400-4423, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4425-4429, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4658-4689, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:1240-1296, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:845-847, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:1177-1179, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:5177-5191, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:2167-2422
How it connects
The reconciler consumes the host-config boundary through the HostConfig type and factory shape rather than importing DOM operations directly. The custom fork exists specifically so third-party renderers can pass a host config as an argument even though the reconciler treats it as a module internally.
For DOM entry points, react-dom imports clearContainer from react-dom-bindings, while event setup comes from DOMPluginEventSystem; this keeps container validation, root bookkeeping, and event registration beside the DOM host operations rather than inside the reconciler.
A new custom renderer therefore needs a host-config object with the operations appropriate to its host tree: context propagation, instance and text creation, child insertion and removal, property updates, commit coordination, and—if supported—hydration and specialized capabilities. The shown custom-renderer shim establishes how that object enters the reconciler; the DOM excerpts provide concrete examples of the implementations to replace.
Sources: packages/react-reconciler/index.js:10-17, packages/react-reconciler/src/forks/ReactFiberConfig.custom.js:10-23, packages/react-dom/src/client/ReactDOMRootFB.js:34-47, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:534-664, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:757-779, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:999-1012, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:1082-1133, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4078-4225
Key takeaways
- The host config is the renderer boundary: the reconciler receives a
HostConfig, while ReactDOM supplies DOM-specific operations. - ReactDOM carries namespace and nesting state through
getRootHostContextandgetChildHostContext. - Real DOM nodes are created by
createInstanceandcreateTextInstance, then assembled and mutated through host operations. - Hydration is a separate matching path that understands elements, text, comment boundaries, and form-state markers.
- A custom renderer follows the same boundary shape but supplies host implementations for its own target environment.
Sources: packages/react-reconciler/index.js:10-17, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:314-367, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:403-418, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:534-664, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:695-701, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:999-1012, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4078-4225, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4227-4254, packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:4400-4423, packages/react-reconciler/src/forks/ReactFiberConfig.custom.js:10-23