1# React Compiler Knowledge Base23This document contains knowledge about the React Compiler gathered during development sessions. It serves as a reference for understanding the codebase architecture and key concepts.45## Project Structure67When modifying the compiler, you MUST read the documentation about that pass in `compiler/packages/babel-plugin-react-compiler/docs/passes/` to learn more about the role of that pass within the compiler.89- `packages/babel-plugin-react-compiler/` - Main compiler package10 - `src/HIR/` - High-level Intermediate Representation types and utilities11 - `src/Inference/` - Effect inference passes (aliasing, mutation, etc.)12 - `src/Validation/` - Validation passes that check for errors13 - `src/Entrypoint/Pipeline.ts` - Main compilation pipeline with pass ordering14 - `src/__tests__/fixtures/compiler/` - Test fixtures15 - `error.todo-*.js` - Unsupported feature, correctly throws Todo error (graceful bailout)16 - `error.bug-*.js` - Known bug, throws wrong error type or incorrect behavior17 - `*.expect.md` - Expected output for each fixture1819## Running Tests2021```bash22# Run all tests23yarn snap2425# Run tests matching a pattern26# Example: yarn snap -p 'error.*'27yarn snap -p <pattern>2829# Run a single fixture in debug mode. Use the path relative to the __tests__/fixtures/compiler directory30# For each step of compilation, outputs the step name and state of the compiled program31# Example: yarn snap -p simple.js -d32yarn snap -p <file-basename> -d3334# Update fixture outputs (also works with -p)35yarn snap -u36```3738## Linting3940```bash41# Run lint on the compiler source42yarn workspace babel-plugin-react-compiler lint43```4445## Formatting4647```bash48# Run prettier on all files (from the react root directory, not compiler/)49yarn prettier-all50```5152## Compiling Arbitrary Files5354Use `yarn snap compile` to compile any file (not just fixtures) with the React Compiler:5556```bash57# Compile a file and see the output58yarn snap compile <path>5960# Compile with debug logging to see the state after each compiler pass61# This is an alternative to `yarn snap -d -p <pattern>` when you don't have a fixture file yet62yarn snap compile --debug <path>63```6465## Minimizing Test Cases6667Use `yarn snap minimize` to automatically reduce a failing test case to its minimal reproduction:6869```bash70# Minimize a file that causes a compiler error71yarn snap minimize <path>7273# Minimize and update the file in-place with the minimized version74yarn snap minimize --update <path>75```7677## Version Control7879This repository uses Sapling (`sl`) for version control. Sapling is similar to Mercurial: there is not staging area, but new/deleted files must be explicitly added/removed.8081```bash82# Check status83sl status8485# Add new files, remove deleted files86sl addremove8788# Commit all changes89sl commit -m "Your commit message"9091# Commit with multi-line message using heredoc92sl commit -m "$(cat <<'EOF'93Summary line9495Detailed description here96EOF97)"98```99100## Key Concepts101102### HIR (High-level Intermediate Representation)103104The compiler converts source code to HIR for analysis. Key types in `src/HIR/HIR.ts`:105106- **HIRFunction** - A function being compiled107 - `body.blocks` - Map of BasicBlocks108 - `context` - Captured variables from outer scope109 - `params` - Function parameters110 - `returns` - The function's return place111 - `aliasingEffects` - Effects that describe the function's behavior when called112113- **Instruction** - A single operation114 - `lvalue` - The place being assigned to115 - `value` - The instruction kind (CallExpression, FunctionExpression, LoadLocal, etc.)116 - `effects` - Array of AliasingEffects for this instruction117118- **Terminal** - Block terminators (return, branch, etc.)119 - `effects` - Array of AliasingEffects120121- **Place** - A reference to a value122 - `identifier.id` - Unique IdentifierId123124- **Phi nodes** - Join points for values from different control flow paths125 - Located at `block.phis`126 - `phi.place` - The result place127 - `phi.operands` - Map of predecessor block to source place128129### AliasingEffects System130131Effects describe data flow and operations. Defined in `src/Inference/AliasingEffects.ts`:132133**Data Flow Effects:**134- `Impure` - Marks a place as containing an impure value (e.g., Date.now() result, ref.current)135- `Capture a -> b` - Value from `a` is captured into `b` (mutable capture)136- `Alias a -> b` - `b` aliases `a`137- `ImmutableCapture a -> b` - Immutable capture (like Capture but read-only)138- `Assign a -> b` - Direct assignment139- `MaybeAlias a -> b` - Possible aliasing140- `CreateFrom a -> b` - Created from source141142**Mutation Effects:**143- `Mutate value` - Value is mutated144- `MutateTransitive value` - Value and transitive captures are mutated145- `MutateConditionally value` - May mutate146- `MutateTransitiveConditionally value` - May mutate transitively147148**Other Effects:**149- `Render place` - Place is used in render context (JSX props, component return)150- `Freeze place` - Place is frozen (made immutable)151- `Create place` - New value created152- `CreateFunction` - Function expression created, includes `captures` array153- `Apply` - Function application with receiver, function, args, and result154155### Hook Aliasing Signatures156157Located in `src/HIR/Globals.ts`, hooks can define custom aliasing signatures to control how data flows through them.158159**Structure:**160```typescript161aliasing: {162 receiver: '@receiver', // The hook function itself163 params: ['@param0'], // Named positional parameters164 rest: '@rest', // Rest parameters (or null)165 returns: '@returns', // Return value166 temporaries: [], // Temporary values during execution167 effects: [ // Array of effects to apply when hook is called168 {kind: 'Freeze', value: '@param0', reason: ValueReason.HookCaptured},169 {kind: 'Assign', from: '@param0', into: '@returns'},170 ],171}172```173174**Common patterns:**1751761. **RenderHookAliasing** (useState, useContext, useMemo, useCallback):177 - Freezes arguments (`Freeze @rest`)178 - Marks arguments as render-time (`Render @rest`)179 - Creates frozen return value180 - Aliases arguments to return1811822. **EffectHookAliasing** (useEffect, useLayoutEffect, useInsertionEffect):183 - Freezes function and deps184 - Creates internal effect object185 - Captures function and deps into effect186 - Returns undefined1871883. **Event handler hooks** (useEffectEvent):189 - Freezes callback (`Freeze @fn`)190 - Aliases input to return (`Assign @fn -> @returns`)191 - NO Render effect (callback not called during render)192193**Example: useEffectEvent**194```typescript195const UseEffectEventHook = addHook(196 DEFAULT_SHAPES,197 {198 positionalParams: [Effect.Freeze], // Takes one positional param199 restParam: null,200 returnType: {kind: 'Function', ...},201 calleeEffect: Effect.Read,202 hookKind: 'useEffectEvent',203 returnValueKind: ValueKind.Frozen,204 aliasing: {205 receiver: '@receiver',206 params: ['@fn'], // Name for the callback parameter207 rest: null,208 returns: '@returns',209 temporaries: [],210 effects: [211 {kind: 'Freeze', value: '@fn', reason: ValueReason.HookCaptured},212 {kind: 'Assign', from: '@fn', into: '@returns'},213 // Note: NO Render effect - callback is not called during render214 ],215 },216 },217 BuiltInUseEffectEventId,218);219220// Add as both names for compatibility221['useEffectEvent', UseEffectEventHook],222['experimental_useEffectEvent', UseEffectEventHook],223```224225**Key insight:** If a hook is missing an `aliasing` config, it falls back to `DefaultNonmutatingHook` which includes a `Render` effect on all arguments. This can cause false positives for hooks like `useEffectEvent` whose callbacks are not called during render.226227## Feature Flags228229Feature flags are configured in `src/HIR/Environment.ts`, for example `enableJsxOutlining`. Test fixtures can override the active feature flags used for that fixture via a comment pragma on the first line of the fixture input, for example:230231```javascript232// enableJsxOutlining @enableNameAnonymousFunctions:false233234...code...235```236237Would enable the `enableJsxOutlining` feature and disable the `enableNameAnonymousFunctions` feature.238239## Rust Port (Active)240241Work is tracked in `compiler/docs/rust-port/` with numbered plan docs.242Rust crates live in `compiler/crates/`.243244### Before implementing from a plan:245- Run `git log --oneline --grep="<plan-name>"` to see what's already done246- Read the plan doc's Remaining Work / Status section247- Only implement what's actually remaining248249### After implementing:250- Update the plan doc's status251- Run `/compiler-verify`252- Ensure `compiler/scripts/test-babel-ast.sh` passes253254## Debugging Tips2552561. Run `yarn snap -p <fixture>` to see full HIR output with effects2572. Look for `@aliasingEffects=` on FunctionExpressions2583. Look for `Impure`, `Render`, `Capture` effects on instructions2594. Check the pass ordering in Pipeline.ts to understand when effects are populated vs validated260261## Error Handling and Fault Tolerance262263The compiler is fault-tolerant: it runs all passes and accumulates errors on the `Environment` rather than throwing on the first error. This lets users see all compilation errors at once.264265**Recording errors** — Passes record errors via `env.recordError(diagnostic)`. Errors are accumulated on `Environment.#errors` and checked at the end of the pipeline via `env.hasErrors()` / `env.aggregateErrors()`.266267**`tryRecord()` wrapper** — In Pipeline.ts, validation passes are wrapped in `env.tryRecord(() => pass(hir))` which catches thrown `CompilerError`s (non-invariant) and records them. Infrastructure/transformation passes are NOT wrapped in `tryRecord()` because later passes depend on their output being structurally valid.268269**Error categories:**270- `CompilerError.throwTodo()` — Unsupported but known pattern. Graceful bailout. Can be caught by `tryRecord()`.271- `CompilerError.invariant()` — Truly unexpected/invalid state. Always throws immediately, never caught by `tryRecord()`.272- Non-`CompilerError` exceptions — Always re-thrown.273274**Key files:** `Environment.ts` (`recordError`, `tryRecord`, `hasErrors`, `aggregateErrors`), `Pipeline.ts` (pass orchestration), `Program.ts` (`tryCompileFunction` handles the `Result`).275276**Test fixtures:** `__tests__/fixtures/compiler/fault-tolerance/` contains multi-error fixtures verifying all errors are reported.
Findings
✓ No findings reported for this file.