[compiler] Claude file/settings (#35523)
Initializes CLAUDE.md and a settings file for the compiler/ directory to help use claude with the compiler. Note that some of the commands here depend on changes to snap from the next PR. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/35523). * #35607 * #35298 * #35596 * #35573 * #35595 * #35539 * #35537 * __->__ #35523
Joseph Savona committed
Jan 23, 2026 at 10:36 UTC
2af6822c2108eabc0228d7809aa27c00bb2ebb53
3 files changed
+225
compiler/.claude/settings.json
renamed
+2
@@ -1,6 +1,8 @@
1
{
2
"permissions": {
3
"allow": [
4
+ "Bash(yarn snap:*)",
5
+ "Bash(yarn snap:build)",
6
"Bash(node scripts/enable-feature-flag.js:*)"
7
],
8
"deny": [],
compiler/.gitignore
+2
@@ -8,7 +8,9 @@ dist
8
.vscode
9
!packages/playground/.vscode
10
testfilter.txt
11
+.claude/settings.local.json
12
13
# forgive
14
*.vsix
15
.vscode-test
16
+
compiler/CLAUDE.md
new
+221
@@ -0,0 +1,221 @@
1
+# React Compiler Knowledge Base
2
+
3
+This document contains knowledge about the React Compiler gathered during development sessions. It serves as a reference for understanding the codebase architecture and key concepts.
4
+
5
+## Project Structure
6
+
7
+- `packages/babel-plugin-react-compiler/` - Main compiler package
8
+ - `src/HIR/` - High-level Intermediate Representation types and utilities
9
+ - `src/Inference/` - Effect inference passes (aliasing, mutation, etc.)
10
+ - `src/Validation/` - Validation passes that check for errors
11
+ - `src/Entrypoint/Pipeline.ts` - Main compilation pipeline with pass ordering
12
+ - `src/__tests__/fixtures/compiler/` - Test fixtures
13
+ - `error.todo-*.js` - Unsupported feature, correctly throws Todo error (graceful bailout)
14
+ - `error.bug-*.js` - Known bug, throws wrong error type or incorrect behavior
15
+ - `*.expect.md` - Expected output for each fixture
16
+
17
+## Running Tests
18
+
19
+```bash
20
+# Run all tests
21
+yarn snap
22
+
23
+# Run tests matching a pattern
24
+# Example: yarn snap -p 'error.*'
25
+yarn snap -p <pattern>
26
+
27
+# Run a single fixture in debug mode. Use the path relative to the __tests__/fixtures/compiler directory
28
+# For each step of compilation, outputs the step name and state of the compiled program
29
+# Example: yarn snap -p simple.js -d
30
+yarn snap -p <file-basename> -d
31
+
32
+# Update fixture outputs (also works with -p)
33
+yarn snap -u
34
+```
35
+
36
+## Version Control
37
+
38
+This repository uses Sapling (`sl`) for version control. Sapling is similar to Mercurial: there is not staging area, but new/deleted files must be explicitlyu added/removed.
39
+
40
+```bash
41
+# Check status
42
+sl status
43
+
44
+# Add new files, remove deleted files
45
+sl addremove
46
+
47
+# Commit all changes
48
+sl commit -m "Your commit message"
49
+
50
+# Commit with multi-line message using heredoc
51
+sl commit -m "$(cat <<'EOF'
52
+Summary line
53
+
54
+Detailed description here
55
+EOF
56
+)"
57
+```
58
+
59
+## Key Concepts
60
+
61
+### HIR (High-level Intermediate Representation)
62
+
63
+The compiler converts source code to HIR for analysis. Key types in `src/HIR/HIR.ts`:
64
+
65
+- **HIRFunction** - A function being compiled
66
+ - `body.blocks` - Map of BasicBlocks
67
+ - `context` - Captured variables from outer scope
68
+ - `params` - Function parameters
69
+ - `returns` - The function's return place
70
+ - `aliasingEffects` - Effects that describe the function's behavior when called
71
+
72
+- **Instruction** - A single operation
73
+ - `lvalue` - The place being assigned to
74
+ - `value` - The instruction kind (CallExpression, FunctionExpression, LoadLocal, etc.)
75
+ - `effects` - Array of AliasingEffects for this instruction
76
+
77
+- **Terminal** - Block terminators (return, branch, etc.)
78
+ - `effects` - Array of AliasingEffects
79
+
80
+- **Place** - A reference to a value
81
+ - `identifier.id` - Unique IdentifierId
82
+
83
+- **Phi nodes** - Join points for values from different control flow paths
84
+ - Located at `block.phis`
85
+ - `phi.place` - The result place
86
+ - `phi.operands` - Map of predecessor block to source place
87
+
88
+### AliasingEffects System
89
+
90
+Effects describe data flow and operations. Defined in `src/Inference/AliasingEffects.ts`:
91
+
92
+**Data Flow Effects:**
93
+- `Impure` - Marks a place as containing an impure value (e.g., Date.now() result, ref.current)
94
+- `Capture a -> b` - Value from `a` is captured into `b` (mutable capture)
95
+- `Alias a -> b` - `b` aliases `a`
96
+- `ImmutableCapture a -> b` - Immutable capture (like Capture but read-only)
97
+- `Assign a -> b` - Direct assignment
98
+- `MaybeAlias a -> b` - Possible aliasing
99
+- `CreateFrom a -> b` - Created from source
100
+
101
+**Mutation Effects:**
102
+- `Mutate value` - Value is mutated
103
+- `MutateTransitive value` - Value and transitive captures are mutated
104
+- `MutateConditionally value` - May mutate
105
+- `MutateTransitiveConditionally value` - May mutate transitively
106
+
107
+**Other Effects:**
108
+- `Render place` - Place is used in render context (JSX props, component return)
109
+- `Freeze place` - Place is frozen (made immutable)
110
+- `Create place` - New value created
111
+- `CreateFunction` - Function expression created, includes `captures` array
112
+- `Apply` - Function application with receiver, function, args, and result
113
+
114
+### Hook Aliasing Signatures
115
+
116
+Located in `src/HIR/Globals.ts`, hooks can define custom aliasing signatures to control how data flows through them.
117
+
118
+**Structure:**
119
+```typescript
120
+aliasing: {
121
+ receiver: '@receiver', // The hook function itself
122
+ params: ['@param0'], // Named positional parameters
123
+ rest: '@rest', // Rest parameters (or null)
124
+ returns: '@returns', // Return value
125
+ temporaries: [], // Temporary values during execution
126
+ effects: [ // Array of effects to apply when hook is called
127
+ {kind: 'Freeze', value: '@param0', reason: ValueReason.HookCaptured},
128
+ {kind: 'Assign', from: '@param0', into: '@returns'},
129
+ ],
130
+}
131
+```
132
+
133
+**Common patterns:**
134
+
135
+1. **RenderHookAliasing** (useState, useContext, useMemo, useCallback):
136
+ - Freezes arguments (`Freeze @rest`)
137
+ - Marks arguments as render-time (`Render @rest`)
138
+ - Creates frozen return value
139
+ - Aliases arguments to return
140
+
141
+2. **EffectHookAliasing** (useEffect, useLayoutEffect, useInsertionEffect):
142
+ - Freezes function and deps
143
+ - Creates internal effect object
144
+ - Captures function and deps into effect
145
+ - Returns undefined
146
+
147
+3. **Event handler hooks** (useEffectEvent):
148
+ - Freezes callback (`Freeze @fn`)
149
+ - Aliases input to return (`Assign @fn -> @returns`)
150
+ - NO Render effect (callback not called during render)
151
+
152
+**Example: useEffectEvent**
153
+```typescript
154
+const UseEffectEventHook = addHook(
155
+ DEFAULT_SHAPES,
156
+ {
157
+ positionalParams: [Effect.Freeze], // Takes one positional param
158
+ restParam: null,
159
+ returnType: {kind: 'Function', ...},
160
+ calleeEffect: Effect.Read,
161
+ hookKind: 'useEffectEvent',
162
+ returnValueKind: ValueKind.Frozen,
163
+ aliasing: {
164
+ receiver: '@receiver',
165
+ params: ['@fn'], // Name for the callback parameter
166
+ rest: null,
167
+ returns: '@returns',
168
+ temporaries: [],
169
+ effects: [
170
+ {kind: 'Freeze', value: '@fn', reason: ValueReason.HookCaptured},
171
+ {kind: 'Assign', from: '@fn', into: '@returns'},
172
+ // Note: NO Render effect - callback is not called during render
173
+ ],
174
+ },
175
+ },
176
+ BuiltInUseEffectEventId,
177
+);
178
+
179
+// Add as both names for compatibility
180
+['useEffectEvent', UseEffectEventHook],
181
+['experimental_useEffectEvent', UseEffectEventHook],
182
+```
183
+
184
+**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.
185
+
186
+## Feature Flags
187
+
188
+Feature 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:
189
+
190
+```javascript
191
+// enableJsxOutlining @enableChangeVariableCodegen:false
192
+
193
+...code...
194
+```
195
+
196
+Would enable the `enableJsxOutlining` feature and disable the `enableChangeVariableCodegen` feature.
197
+
198
+## Debugging Tips
199
+
200
+1. Run `yarn snap -p <fixture>` to see full HIR output with effects
201
+2. Look for `@aliasingEffects=` on FunctionExpressions
202
+3. Look for `Impure`, `Render`, `Capture` effects on instructions
203
+4. Check the pass ordering in Pipeline.ts to understand when effects are populated vs validated
204
+
205
+## Error Handling for Unsupported Features
206
+
207
+When the compiler encounters an unsupported but known pattern, use `CompilerError.throwTodo()` instead of `CompilerError.invariant()`. Todo errors cause graceful bailouts in production; Invariant errors are hard failures indicating unexpected/invalid states.
208
+
209
+```typescript
210
+// Unsupported but expected pattern - graceful bailout
211
+CompilerError.throwTodo({
212
+ reason: `Support [description of unsupported feature]`,
213
+ loc: terminal.loc,
214
+});
215
+
216
+// Invariant is for truly unexpected/invalid states - hard failure
217
+CompilerError.invariant(false, {
218
+ reason: `Unexpected [thing]`,
219
+ loc: terminal.loc,
220
+});
221
+```