Fiber has been React's core engine since v16, but most devs never look at how it actually works. Here's a plain-English breakdown.
The problem before Fiber
The old Stack Reconciler would walk the entire component tree in one uninterruptible pass. A slow render locked the main thread completely. Typing, clicking, scrolling — all blocked.
What Fiber changed
Fiber breaks rendering into small units of work (one fiber per component). Each fiber is a JS object with child, sibling, and return pointers — a linked list structure that lets React walk the tree incrementally and pause mid-render.
The two phases
Render phase — runs component functions, diffs old vs new. Invisible to the user. Can pause, restart, or be thrown away entirely.
Commit phase — writes DOM changes. Synchronous and atomic. Users only ever see a complete UI.
This split directly explains:
- Why
useEffectruns after paint (scheduled after commit) - Why
useLayoutEffectruns before paint (fires during commit) - Why Strict Mode double-invokes components (render phase can restart)
Lanes (priority system)
Every update gets a lane:
-
SyncLane— clicks, keypresses (highest priority) -
DefaultLane— regular state updates -
TransitionLane— updates wrapped inuseTransition -
IdleLane— background work
High-priority lanes always run first. This is what makes useTransition work.
Double buffering
React keeps two trees: the current tree (on screen) and a work-in-progress tree (built off-screen). On commit, they swap. You never see a half-rendered UI.
I wrote a full deep-dive with diagrams covering all of this in detail:
👉 https://devencyclopedia.com/blog/react-fiber-architecture-explained
Top comments (0)