React Internals: from createRoot to pixels

React does its work in two phases. The render phase is pure and can be interrupted (in practice only for transition, retry and idle work, because the first mount and clicks render…

Published
Reading time
2 min read
React InternalsPart 00 · 1 of 18
Summary: TL;DR

React does its work in two phases. The render phase is pure and can be interrupted (in practice only for transition, retry and idle work, because the first mount and clicks render synchronously): it calls your components and diffs the old fiber tree against the new one. The commit phase is synchronous: it changes the DOM and runs effects. Everything else exists to decide when to run those phases (lanes + Scheduler) and how little work they can get away with (bailouts). The React Compiler leaves that machinery alone. It rewrites your components so they hand React the same objects when nothing changed, which lets the existing bailouts kick in.

All pages are pinned to React v19.3.1. Footnotes link to the v19.3.1 tag on GitHub with exact line ranges. The compiler examples were compiled with the real babel-plugin-react-compiler@1.0.0.

Start here: the two stories

  1. First Render Walkthrough: createRoot(el).render(<App/>) all the way to the first paint.
  2. setState Walkthrough: a click calls setCount(c => c + 1), and this page follows it until you see the new number.

Each walkthrough is the short narrative. The pages below are the deep dives it links into.

The big picture

Flowchart

Diagram source:

flowchart LR
    A[JSX / createElement] --> B[createRoot]
    B --> C[root.render / setState]
    C --> D[requestUpdateLane<br/>enqueue update]
    D --> E[scheduleUpdateOnFiber<br/>ensureRootIsScheduled]
    E --> F[Scheduler / microtask]
    F --> G[Work loop<br/>render phase]
    G --> H[beginWork<br/>hooks + reconcile]
    H --> I[completeWork<br/>DOM nodes]
    I --> G
    G --> J[commitRoot<br/>mutation → layout]
    J --> K[Browser paint]
    K --> L[Passive effects<br/>useEffect]

Deep dives

Setup

  • 01 · Bootstrap: how react, react-dom, the reconciler and the scheduler fit together, what JSX compiles to, and how useState reaches the reconciler.
  • 02 · createRoot: FiberRootNode, the HostRoot fiber, and root event listeners.
  • 03 · root.render: the first update object and how it gets scheduled.

Core machinery

Render phase

Commit phase

  • 09 · Commit Phase: DOM mutation, the tree swap, layout effects, paint, then passive effects.

Updates

React Compiler

Reading order suggestions

  • Quick tour: 20 → 21 → 15.
  • Full depth: 01 → 15 in order, then reread 20 and 21.
  • Only care about the compiler: 07 (bailout section) → 14 → 15.