A17 · Part 3 · Advanced
Custom renderers
React is not a DOM library. The DOM is one target among several.
07On this page
The split nobody notices
React is two packages doing two jobs.
| Package | Does |
|---|---|
react | Components, hooks, state, context, the element format. Knows nothing about the DOM. |
react-reconciler | Diffing, scheduling, priorities, the fiber tree. Also knows nothing about the DOM. |
react-dom | A host config: how to create a node, set a property, insert a child. |
Swap the third and everything else keeps working. That is why
useState behaves identically in React Native, and why the
reconciler chapter never mentions elements.
What already exists
| Renderer | Targets |
|---|---|
| React Native | Native iOS and Android views |
| React Three Fiber | A three.js scene graph — WebGL |
| Ink | A terminal. Used by real CLIs. |
| React PDF | A PDF document |
| React Test Renderer | A plain object tree, for assertions |
None of these is a fork. They are host configs over the same reconciler, which is the point: the component model turned out to be more general than the DOM.
A host config, roughly
const config = {
createInstance(type, props) { return new SceneNode(type, props); },
appendChild(parent, child) { parent.add(child); },
removeChild(parent, child) { parent.remove(child); },
commitUpdate(instance, _t, oldProps, newProps) { instance.apply(newProps); },
prepareUpdate(_i, _t, oldProps, newProps) { return diff(oldProps, newProps); },
shouldSetTextContent() { return false; },
getPublicInstance(instance) { return instance; },
supportsMutation: true,
};
const reconciler = Reconciler(config);
const container = reconciler.createContainer(root, 0, null, false, null, "", console.error, null);
reconciler.updateContainer(<App />, container, null, null);
Thirty-odd methods, and the reconciler supplies everything else — hooks, context, Suspense, transitions, the diff. You describe how to create, insert, update and remove a node in your world; React decides when.
Mutation, persistence and no-op
- Mutation mode — nodes are modified in place. The DOM works this way.
- Persistence mode — every change produces a new node tree. Used where the host is immutable, as in some native frameworks.
- No-op — nothing is committed anywhere. This is how the test renderer works.
Why this is worth understanding even if you never write one
It explains the boundaries
Everything React "cannot do" — measure a DOM node during render, read layout, focus something — is not a limitation of React. It is that those are host concerns, and the reconciler deliberately knows nothing about a host. That is exactly why refs and effects exist: they are the sanctioned doors from React's world into the host's.
It also explains why the reconciler's rules are so strict. Purity, interruptibility, no side effects during render — those hold because the same algorithm has to be correct for a terminal, a 3D scene and a PDF, not just a browser.
The realistic reasons to build one
- You own a rendering target — a canvas engine, a game UI, embedded hardware — and want the component model over it.
- A declarative wrapper over an imperative scene graph, which is exactly what React Three Fiber is.
- Curiosity. Writing one is the fastest way to actually understand the reconciler.
Not to render to the DOM differently. react-dom is one of the most
battle-tested pieces of software on the web, and a custom renderer for it
would be slower and wrong in ways you would find one at a time.
The idea to take away
React is a scheduling and diffing engine for tree-shaped UIs, with a pluggable back end. Components, hooks and state are the front end and are target-independent. Once that clicks, React Native stops looking like a separate framework, and the strictness of the render phase stops looking arbitrary.
Interview answer, one sentence
"React splits into the component model, a host-agnostic reconciler, and a host config that says how to create and update nodes — which is why the same hooks work in React Native, Ink and React Three Fiber. Knowing that explains why render must be pure and why refs and effects exist: they are the only sanctioned doors to the host."
Opens in the editor: write it, run it, and check it against real tests.
All 54 for this level →Finished reading?
0 of 57 chapters read in this series