Fiber Architecture
A Fiber is the reconciler’s internal record for one unit of work: it combines identity, tree links, pending and remembered data, scheduling lanes, and effect flags.
This structure exists so React can build a second tree without immediately replacing the committed one. createWorkInProgress uses a pooled double-buffering strategy and creates the alternate lazily.
Sources: packages/react-reconciler/src/ReactFiber.js:134-207, packages/react-reconciler/src/ReactFiber.js:323-437
Core concepts
Fiber node
A Fiber node is the reconciler record that represents work for a component, host node, fragment, root, or special runtime construct. FiberNode stores identity fields, tree links, props, state, dependencies, scheduling lanes, effects, and an alternate.
this.tag = tag;
this.key = key;
this.elementType = null;
this.type = null;
this.stateNode = null;
this.return = null;
this.child = null;
this.sibling = null;
this.index = 0;
this.pendingProps = pendingProps;
this.memoizedProps = null;
this.memoizedState = null;
this.alternate = null;These fields show that a Fiber is more than a description of what to render: it also records where the node sits, what it previously remembered, and how another version is connected to it.
Sources: packages/react-reconciler/src/ReactFiber.js:134-207, packages/react-reconciler/src/ReactFiber.js:141-173
React element
A React element is the input record from which React creates a Fiber, carrying type, key, and props, with _owner used in development.
createFiberFromElement passes those element values, together with mode and lanes, to createFiberFromTypeAndProps; the resulting Fiber then gains reconciler-owned state and links. This is why an element and a Fiber are related but not interchangeable: the element describes the requested output, while the Fiber carries the ongoing work record.
Sources: packages/react-reconciler/src/ReactFiber.js:739-750, packages/react-reconciler/src/ReactFiber.js:751-764, packages/react-reconciler/src/ReactFiber.js:134-207
Current and work-in-progress trees
The current tree is the version already associated with the root, while the work-in-progress tree is the alternate version being prepared. createWorkInProgress reads current.alternate, creates it when absent, and links both Fibers through their alternate fields.
The two versions share stable identity-oriented information but keep render-mutated data separate. For example, createWorkInProgress copies props, state, queues, lanes, and child links while cloning dependencies because render mutates that object.
Sources: packages/react-reconciler/src/ReactFiber.js:323-351, packages/react-reconciler/src/ReactFiber.js:381-407
Tags and flags
A tag identifies what kind of work a Fiber represents, while flags record work or effects associated with that Fiber.
The tag is selected from the resolved input type: functions become FunctionComponent or ClassComponent, strings become host tags, and special React types select dedicated tags.
| Category | Examples | Meaning |
|---|---|---|
| Component | FunctionComponent, ClassComponent | Function and class component work |
| Host output | HostComponent, HostText | Host elements and text |
| Tree structure | HostRoot, HostPortal, Fragment | Root, portal, and fragment structure |
| Context and indirection | ContextProvider, ContextConsumer, ForwardRef | Context and forwarded-ref work |
| Async or visibility | SuspenseComponent, SuspenseListComponent, OffscreenComponent | Suspense, list coordination, and hidden content |
| Special runtime nodes | Profiler, ScopeComponent, TracingMarkerComponent | Profiling, scope, and transition tracing |
| Exceptional state | DehydratedFragment, Throw | Dehydrated content and thrown work |
These tags are constants in ReactWorkTags.js, and the constructors assign them when creating specialized Fibers.
Flags are bit values, so a Fiber can carry several independent conditions at once. The base values include Placement, Update, ChildDeletion, Ref, Passive, Visibility, and StoreConsistency.
| Flag or mask | Meaning in the shown implementation |
|---|---|
NoFlags | No effect flags are set |
Placement | Placement work is recorded |
Update | Update work is recorded |
ChildDeletion | Child deletion work is recorded |
Ref | Ref-related work is recorded |
Passive | Passive-effect work is recorded |
Visibility | Visibility-related work is recorded |
MutationMask | Groups placement, update, deletion, ref, hydration, visibility, and form-reset work |
LayoutMask | Groups update, callback, ref, and visibility work |
PassiveMask | Groups passive, visibility, and child-deletion work |
StaticMask | Groups static layout, passive, ref, suspension, transition, portal, and fork markers |
The masks are combinations of individual flags used to test phases or classes of work; for example, MutationMask, LayoutMask, PassiveMask, and StaticMask are defined as bitwise combinations.
Sources: packages/react-reconciler/src/ReactWorkTags.js:44, packages/react-reconciler/src/ReactFiberFlags.js:18, packages/react-reconciler/src/ReactFiber.js:562-592, packages/react-reconciler/src/ReactFiber.js:594-651, packages/react-reconciler/src/ReactWorkTags.js:46, packages/react-reconciler/src/ReactWorkTags.js:47, packages/react-reconciler/src/ReactWorkTags.js:48, packages/react-reconciler/src/ReactWorkTags.js:49, packages/react-reconciler/src/ReactWorkTags.js:50, packages/react-reconciler/src/ReactWorkTags.js:53, packages/react-reconciler/src/ReactWorkTags.js:54, packages/react-reconciler/src/ReactWorkTags.js:55, packages/react-reconciler/src/ReactWorkTags.js:56, packages/react-reconciler/src/ReactWorkTags.js:62, packages/react-reconciler/src/ReactWorkTags.js:63, packages/react-reconciler/src/ReactWorkTags.js:64, packages/react-reconciler/src/ReactWorkTags.js:67, packages/react-reconciler/src/ReactWorkTags.js:61, packages/react-reconciler/src/ReactWorkTags.js:71, packages/react-reconciler/src/ReactFiberFlags.js:20, packages/react-reconciler/src/ReactFiberFlags.js:120-128, packages/react-reconciler/src/ReactFiberFlags.js:129, packages/react-reconciler/src/ReactFiberFlags.js:132, packages/react-reconciler/src/ReactFiberFlags.js:141-150
How a Fiber is created
An element enters through createFiberFromElement, which extracts the element’s type, key, and props and delegates classification to createFiberFromTypeAndProps. The classifier chooses a work tag and may delegate special values to constructors such as createFiberFromFragment, createFiberFromSuspense, or createFiberFromProfiler.
The selected allocator is createFiber, which chooses either the object implementation or the class implementation according to enableObjectFiber. The class implementation constructs a FiberNode, while the object implementation initializes the equivalent fields in an object.
The following call path captures the ordinary element-to-Fiber hand-off:
Evidence
- react-elementpackages/react-reconciler/src/ReactFiber.js:739
- type-classifierpackages/react-reconciler/src/ReactFiber.js:554
- fiber-allocatorpackages/react-reconciler/src/ReactFiber.js:299
The same allocator is used for text, portals, fragments, Suspense, Offscreen content, and thrown values; those constructors set the tag, lanes, and any specialized stateNode or elementType fields.
Sources: packages/react-reconciler/src/ReactFiber.js:739-758, packages/react-reconciler/src/ReactFiber.js:568-615, packages/react-reconciler/src/ReactFiber.js:299-301, packages/react-reconciler/src/ReactFiber.js:222-230, packages/react-reconciler/src/ReactFiber.js:232-297, packages/react-reconciler/src/ReactFiber.js:767-776, packages/react-reconciler/src/ReactFiber.js:821-831, packages/react-reconciler/src/ReactFiber.js:845-854, packages/react-reconciler/src/ReactFiber.js:923-931, packages/react-reconciler/src/ReactFiber.js:941-955, packages/react-reconciler/src/ReactFiber.js:957-965
How the double buffer is maintained
When an update needs a new render version, createWorkInProgress reuses current.alternate if it exists; otherwise it lazily allocates the other Fiber and links the pair in both directions. This limits the model to the current version and one reusable work-in-progress version rather than allocating a permanently growing chain.
Before reuse, the work-in-progress Fiber receives the new pendingProps, clears transient effect data, preserves static flags, and copies the current Fiber’s child, memoized props, state, update queue, lanes, and tree links.
If rendering must be restarted, resetWorkInProgress preserves only static flags and Placement, then either restores initial values for a Fiber without a current alternate or restores cloned values from its current counterpart. Dependencies are cloned again because they are mutated during render and cannot be shared with the current Fiber.
The supplied excerpts identify the commit boundary as the point where the work-in-progress is swapped in for current queue state: the current queue pointer is updated during commit when the work-in-progress is swapped in. The exact root assignment is outside the shown lines, so this page treats commit as the swap boundary without claiming a particular assignment statement.
Sources: packages/react-reconciler/src/ReactFiber.js:323-352, packages/react-reconciler/src/ReactFiber.js:325-330, packages/react-reconciler/src/ReactFiber.js:353-413, packages/react-reconciler/src/ReactFiber.js:440-490, packages/react-reconciler/src/ReactFiber.js:501-516, packages/react-reconciler/src/ReactFiberClassUpdateQueue.js:19-25
How it connects
Fiber creation is the bridge from React elements to reconciliation; the element and component contracts are described in Element Types & Components. The resulting tree is traversed and rebuilt by Render Phase, while scheduling decisions are represented by lanes and driven through Lanes & Priority and Work Loop & Scheduling.
Flags become actionable during Commit Phase, where mutation, layout, and passive categories determine which kinds of work are considered. Their grouping is explicit in MutationMask, LayoutMask, and PassiveMask. Host-specific stateNode behavior connects Fibers to ReactDOM Host Config, while alternate trees and commit reporting connect to DevTools Integration Hook.
Sources: packages/react-reconciler/src/ReactFiber.js:323-437, packages/react-reconciler/src/ReactFiberFlags.js:120-128, packages/react-reconciler/src/ReactFiberFlags.js:129, packages/react-reconciler/src/ReactFiberFlags.js:132, packages/react-reconciler/src/ReactFiber.js:134-207
Key takeaways
- A Fiber is a mutable reconciler record; a React element is the input used to create one.
tagidentifies the kind of work, whileflagsand masks record work categories.alternatelinks the current and work-in-progress versions.createWorkInProgressreuses the alternate and copies render inputs while isolating render-mutated dependencies.- The shown code places the current/work-in-progress swap at commit, though the exact root assignment is outside the excerpts.