Compiler Architecture
React Compiler transforms React code through a multi-stage pipeline consisting of over 55 distinct compiler passes organized into seven major phases.Pipeline Overview
The compilation pipeline is defined inpackages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts and executes passes in a specific order:
Phase 1: HIR Construction
1. Lower (BuildHIR)
File:src/HIR/BuildHIR.ts
Converts Babel AST to High-level Intermediate Representation (HIR).
Key Operations:
- Creates control-flow graph (CFG) with basic blocks
- Resolves identifiers and bindings
- Converts expressions to instructions
- Makes control flow explicit (if/else, loops, etc.)
2. EnterSSA
File:src/SSA/EnterSSA.ts
Converts HIR to Static Single Assignment (SSA) form.
Key Operations:
- Each variable assigned exactly once
- Inserts phi nodes at control flow merge points
- Creates unique identifiers for each assignment
3. EliminateRedundantPhi
File:src/SSA/EliminateRedundantPhi.ts
Removes unnecessary phi nodes where all operands are identical.
Phase 2: Early Optimization
4. ConstantPropagation
File:src/Optimization/ConstantPropagation.ts
Implements sparse conditional constant propagation.
5. DeadCodeElimination
File:src/Optimization/DeadCodeElimination.ts
Removes unreferenced instructions and unreachable blocks.
Phase 3: Type & Effect Inference
6. InferTypes
File:src/TypeInference/InferTypes.ts
Infers types using constraint-based unification.
Inferred Types:
Primitive: numbers, strings, booleans, null, undefinedObject: objects with shape informationFunction: functions and hooksArray: array typesPoly: polymorphic types
7. AnalyseFunctions
File:src/Inference/AnalyseFunctions.ts
Analyzes nested functions to determine their effects and captures.
8. InferMutationAliasingEffects
File:src/Inference/InferMutationAliasingEffects.ts
Infers mutation and aliasing through abstract interpretation.
Effect Types:
9. InferMutationAliasingRanges
File:src/Inference/InferMutationAliasingRanges.ts
Computes mutable ranges (instruction ranges where values can be mutated).
10. InferReactivePlaces
File:src/Inference/InferReactivePlaces.ts
Marks places as reactive if they:
- Are component props
- Are hook return values
- Are derived from reactive places
- Are used in JSX (render context)
Phase 4: Reactive Scope Inference
11. InferReactiveScopeVariables
File:src/ReactiveScopes/InferReactiveScopeVariables.ts
Groups co-mutating variables into reactive scopes.
Algorithm:
- Identify value blocks (sets of instructions creating a value)
- Compute dependencies for each value
- Group values with shared dependencies
- Create scope boundaries
12. RewriteInstructionKindsBasedOnReassignment
File:src/SSA/RewriteInstructionKindsBasedOnReassignment.ts
Converts SSA loads to context loads for reassigned variables.
13-15. Scope Alignment
Files:src/ReactiveScopes/AlignMethodCallScopes.tssrc/ReactiveScopes/AlignObjectMethodScopes.tssrc/ReactiveScopes/AlignReactiveScopesToBlockScopesHIR.ts
- Method call receivers
- Object method boundaries
- Control flow block boundaries
16-17. Scope Construction
Files:src/HIR/MergeOverlappingReactiveScopesHIR.tssrc/HIR/BuildReactiveScopeTerminalsHIR.ts
18-20. Scope Refinement
Files:src/ReactiveScopes/FlattenReactiveLoopsHIR.tssrc/ReactiveScopes/FlattenScopesWithHooksOrUseHIR.tssrc/HIR/PropagateScopeDependenciesHIR.ts
Phase 5: Reactive Function Construction
21. BuildReactiveFunction
File:src/ReactiveScopes/BuildReactiveFunction.ts
Converts HIR control-flow graph to ReactiveFunction tree structure.
Transformation:
Phase 6: Reactive Function Optimization
22-25. Pruning Passes
Files:src/ReactiveScopes/PruneUnusedLabels.tssrc/ReactiveScopes/PruneNonEscapingScopes.tssrc/ReactiveScopes/PruneNonReactiveDependencies.tssrc/ReactiveScopes/PruneUnusedScopes.ts
- Unused labels
- Non-escaping scopes (values that don’t escape function)
- Non-reactive dependencies
- Empty or unreferenced scopes
26-28. Scope Optimization
Files:src/ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.tssrc/ReactiveScopes/PruneAlwaysInvalidatingScopes.tssrc/ReactiveScopes/PropagateEarlyReturns.ts
- Merges scopes that always invalidate together
- Removes always-invalidating scopes
- Handles early returns
29. PromoteUsedTemporaries
File:src/ReactiveScopes/PromoteUsedTemporaries.ts
Promotes temporary variables to named variables when referenced across scopes.
Phase 7: Code Generation
30. RenameVariables
File:src/ReactiveScopes/RenameVariables.ts
Ensures unique variable names in the output.
31. CodegenReactiveFunction
File:src/ReactiveScopes/CodegenReactiveFunction.ts
Generates final Babel AST with memoization.
Output Structure:
Validation Passes
Validation passes run throughout the pipeline: Hook Validation:ValidateHooksUsage: Rules of Hooks complianceValidateUseMemo: useMemo callback requirements
ValidateLocalsNotReassignedAfterRender: Mutation safetyValidateNoSetStateInRender: setState timingValidateNoSetStateInEffects: Effect performance
ValidateExhaustiveDependencies: Complete dependenciesValidateMemoizedEffectDependencies: Effect memoizationValidatePreservedManualMemoization: Manual memo preservation
ValidateNoCapitalizedCalls: Component vs function callsValidateNoJSXInTryStatement: Error boundary usageValidateNoRefAccessInRender: Ref access constraintsValidateSourceLocations: Source map correctness
Optional Transformations
These run conditionally based on configuration:TransformFire
File:src/Transform/TransformFire.tsFlag:
enableFire
Transforms fire() calls in effects.
LowerContextAccess
File:src/Optimization/LowerContextAccess.tsFlag:
lowerContextAccess
Optimizes React context access with selectors.
OutlineJsx
File:src/Optimization/OutlineJsx.tsFlag:
enableJsxOutlining
Extracts static JSX into separate components.
OutlineFunctions
File:src/Optimization/OutlineFunctions.tsFlag:
enableFunctionOutlining
Outlines pure functions for better memoization.
InferEffectDependencies
File:src/Inference/InferEffectDependencies.tsFlag:
inferEffectDependencies
Auto-infers and inserts effect dependencies.
Data Structures
HIR Types
File:src/HIR/HIR.ts
ReactiveFunction
File:src/ReactiveScopes/ReactiveFunction.ts
Performance Characteristics
Pass Complexity
- Lowering: O(n) where n = AST nodes
- SSA Conversion: O(n + e) where e = CFG edges
- Type Inference: O(n²) worst case (unification)
- Effect Inference: O(n·d) where d = average dependencies
- Scope Inference: O(n·s) where s = scope count
- Codegen: O(n + s)
Memory Usage
- HIR: ~200 bytes per instruction
- Type variables: ~50 bytes each
- Reactive scopes: ~100 bytes + dependencies
- Total: ~1-5MB for typical component
Debugging
Enable Debug Output
Implement a logger to see each pass:Test Runner
Use thesnap test runner:
Next Steps
HIR
Understand the intermediate representation
Optimization Passes
Learn about specific optimizations
Contributing
Contribute to the compiler
Configuration
Configure compiler behavior