Skip to content

Commit 095fd36

Browse files
committed
[compiler] Rewrite React Compiler Docs
We've received [feedback](https://bsky.app/profile/danabra.mov/post/3lr46ciujjs2r) that the compiler docs are difficult to understand and not prominent enough that people don't realize the compiler is a serious project and is near stable. This PR rewrites the whole compiler doc section, giving it its own category as well as a standalone reference page. Preview: https://react-dev-git-pr7868-fbopensource.vercel.app/
1 parent 84a5696 commit 095fd36

23 files changed

+2413
-351
lines changed

src/content/learn/react-compiler.md

Lines changed: 0 additions & 346 deletions
This file was deleted.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
title: Debugging and Troubleshooting
3+
---
4+
5+
<Intro>
6+
This guide helps you identify and fix issues when using React Compiler. Learn how to debug compilation problems and resolve common issues.
7+
</Intro>
8+
9+
<YouWillLearn>
10+
11+
* The difference between compiler errors and runtime issues
12+
* Common patterns that break compilation
13+
* Step-by-step debugging workflow
14+
15+
</YouWillLearn>
16+
17+
## Understanding Compiler Behavior {/*understanding-compiler-behavior*/}
18+
19+
React Compiler is designed to handle code that follows the [Rules of React](/reference/rules). When it encounters code that might break these rules, it safely skips optimization rather than risk changing your app's behavior.
20+
21+
### Compiler Errors vs Runtime Issues {/*compiler-errors-vs-runtime-issues*/}
22+
23+
**Compiler errors** occur at build time and prevent your code from compiling. These are rare because the compiler is designed to skip problematic code rather than fail.
24+
25+
**Runtime issues** occur when compiled code behaves differently than expected. Most of the time, if you encounter an issue with React Compiler, it's a runtime issue. This typically happens when your code violates the Rules of React in subtle ways that the compiler couldn't detect, and the compiler mistakenly compiled a component it should have skipped.
26+
27+
When debugging runtime issues, focus your efforts on finding Rules of React violations in the affected components that were not detected by the ESLint rule. The compiler relies on your code following these rules, and when they're broken in ways it can't detect, that's when runtime problems occur.
28+
29+
30+
## Common Breaking Patterns {/*common-breaking-patterns*/}
31+
32+
One of the main ways React Compiler can break your app is if your code was written to rely on memoization for correctness. This means your app depends on specific values being memoized to work properly. Since the compiler may memoize differently than your manual approach, this can lead to unexpected behavior like effects over-firing, infinite loops, or missing updates.
33+
34+
Common scenarios where this occurs:
35+
36+
- **Effects that rely on referential equality** - When effects depend on objects or arrays maintaining the same reference across renders
37+
- **Dependency arrays that need stable references** - When unstable dependencies cause effects to fire too often or create infinite loops
38+
- **Conditional logic based on reference checks** - When code uses referential equality checks for caching or optimization
39+
40+
## Debugging Workflow {/*debugging-workflow*/}
41+
42+
Follow these steps when you encounter issues:
43+
44+
### Compiler Build Errors {/*compiler-build-errors*/}
45+
46+
If you encounter a compiler error that unexpectedly breaks your build, this is likely a bug in the compiler. Report it to the [facebook/react](https://github.com/facebook/react/issues) repository with:
47+
- The error message
48+
- The code that caused the error
49+
- Your React and compiler versions
50+
51+
### Runtime Issues {/*runtime-issues*/}
52+
53+
For runtime behavior issues:
54+
55+
### 1. Temporarily Disable Compilation {/*temporarily-disable-compilation*/}
56+
57+
Use `"use no memo"` to isolate whether an issue is compiler-related:
58+
59+
```js
60+
function ProblematicComponent() {
61+
"use no memo"; // Skip compilation for this component
62+
// ... rest of component
63+
}
64+
```
65+
66+
If the issue disappears, it's likely related to a Rules of React violation.
67+
68+
You can also try removing manual memoization (useMemo, useCallback, memo) from the problematic component to verify that your app works correctly without any memoization. If the bug still occurs when all memoization is removed, you have a Rules of React violation that needs to be fixed.
69+
70+
### 2. Fix Issues Step by Step {/*fix-issues-step-by-step*/}
71+
72+
1. Identify the root cause (often memoization-for-correctness)
73+
2. Test after each fix
74+
3. Remove `"use no memo"` once fixed
75+
4. Verify the component shows the ✨ badge in React DevTools
76+
77+
## Reporting Compiler Bugs {/*reporting-compiler-bugs*/}
78+
79+
If you believe you've found a compiler bug:
80+
81+
1. **Verify it's not a Rules of React violation** - Check with ESLint
82+
2. **Create a minimal reproduction** - Isolate the issue in a small example
83+
3. **Test without the compiler** - Confirm the issue only occurs with compilation
84+
4. **File an [issue](https://github.com/facebook/react/issues/new?template=compiler_bug_report.yml)**:
85+
- React and compiler versions
86+
- Minimal reproduction code
87+
- Expected vs actual behavior
88+
- Any error messages
89+
90+
## Next Steps {/*next-steps*/}
91+
92+
- Review the [Rules of React](/reference/rules) to prevent issues
93+
- Check the [incremental adoption guide](/learn/react-compiler/incremental-adoption) for gradual rollout strategies
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
---
2+
title: Incremental Adoption
3+
---
4+
5+
<Intro>
6+
React Compiler can be adopted incrementally, allowing you to try it on specific parts of your codebase first. This guide shows you how to gradually roll out the compiler in existing projects.
7+
</Intro>
8+
9+
<YouWillLearn>
10+
11+
* Why incremental adoption is recommended
12+
* Using Babel overrides for directory-based adoption
13+
* Using the "use memo" directive for opt-in compilation
14+
* Using the "use no memo" directive to exclude components
15+
* Runtime feature flags with gating
16+
* Monitoring your adoption progress
17+
18+
</YouWillLearn>
19+
20+
## Why Incremental Adoption? {/*why-incremental-adoption*/}
21+
22+
While React Compiler is designed to handle most React code automatically, adopting it incrementally allows you to:
23+
24+
- Test the compiler on a small portion of your app first
25+
- Identify and fix any Rules of React violations
26+
- Build confidence before expanding to your entire codebase
27+
- Minimize risk in production applications
28+
29+
## Approaches to Incremental Adoption {/*approaches-to-incremental-adoption*/}
30+
31+
There are three main approaches to adopt React Compiler incrementally:
32+
33+
1. **Babel overrides** - Apply the compiler to specific directories
34+
2. **Opt-in with "use memo"** - Only compile components that explicitly opt in
35+
3. **Runtime gating** - Control compilation with feature flags
36+
37+
All approaches allow you to test the compiler on specific parts of your application before full rollout.
38+
39+
## Directory-Based Adoption with Babel Overrides {/*directory-based-adoption*/}
40+
41+
Babel's `overrides` option lets you apply different plugins to different parts of your codebase. This is ideal for gradually adopting React Compiler directory by directory.
42+
43+
### Basic Configuration {/*basic-configuration*/}
44+
45+
Start by applying the compiler to a specific directory:
46+
47+
```js
48+
// babel.config.js
49+
module.exports = {
50+
plugins: [
51+
// Global plugins that apply to all files
52+
],
53+
overrides: [
54+
{
55+
test: './src/modern/**/*.{js,jsx,ts,tsx}',
56+
plugins: [
57+
'babel-plugin-react-compiler'
58+
]
59+
}
60+
]
61+
};
62+
```
63+
64+
### Expanding Coverage {/*expanding-coverage*/}
65+
66+
As you gain confidence, add more directories:
67+
68+
```js
69+
// babel.config.js
70+
module.exports = {
71+
plugins: [
72+
// Global plugins
73+
],
74+
overrides: [
75+
{
76+
test: ['./src/modern/**/*.{js,jsx,ts,tsx}', './src/features/**/*.{js,jsx,ts,tsx}'],
77+
plugins: [
78+
'babel-plugin-react-compiler'
79+
]
80+
},
81+
{
82+
test: './src/legacy/**/*.{js,jsx,ts,tsx}',
83+
plugins: [
84+
// Different plugins for legacy code
85+
]
86+
}
87+
]
88+
};
89+
```
90+
91+
### With Compiler Options {/*with-compiler-options*/}
92+
93+
You can also configure compiler options per override:
94+
95+
```js
96+
// babel.config.js
97+
module.exports = {
98+
plugins: [],
99+
overrides: [
100+
{
101+
test: './src/experimental/**/*.{js,jsx,ts,tsx}',
102+
plugins: [
103+
['babel-plugin-react-compiler', {
104+
compilationMode: 'annotation', // Only compile "use memo" components
105+
panicThreshold: 'NONE' // More permissive for experimental code
106+
}]
107+
]
108+
},
109+
{
110+
test: './src/production/**/*.{js,jsx,ts,tsx}',
111+
plugins: [
112+
['babel-plugin-react-compiler', {
113+
panicThreshold: 'CRITICAL_ERRORS' // Stricter for production code
114+
}]
115+
]
116+
}
117+
]
118+
};
119+
```
120+
121+
122+
## Opt-in Mode with "use memo" {/*opt-in-mode-with-use-memo*/}
123+
124+
For maximum control, you can use `compilationMode: 'annotation'` to only compile components and hooks that explicitly opt in with the `"use memo"` directive.
125+
126+
<Note>
127+
This approach gives you fine-grained control over individual components and hooks. It's useful when you want to test the compiler on specific components without affecting entire directories.
128+
</Note>
129+
130+
### Annotation Mode Configuration {/*annotation-mode-configuration*/}
131+
132+
```js
133+
// babel.config.js
134+
module.exports = {
135+
plugins: [
136+
['babel-plugin-react-compiler', {
137+
compilationMode: 'annotation',
138+
}],
139+
],
140+
};
141+
```
142+
143+
### Using the Directive {/*using-the-directive*/}
144+
145+
Add `"use memo"` at the beginning of functions you want to compile:
146+
147+
```js
148+
function TodoList({ todos }) {
149+
"use memo"; // Opt this component into compilation
150+
151+
const sortedTodos = todos.slice().sort();
152+
153+
return (
154+
<ul>
155+
{sortedTodos.map(todo => (
156+
<TodoItem key={todo.id} todo={todo} />
157+
))}
158+
</ul>
159+
);
160+
}
161+
162+
function useSortedData(data) {
163+
"use memo"; // Opt this hook into compilation
164+
165+
return data.slice().sort();
166+
}
167+
```
168+
169+
With `compilationMode: 'annotation'`, you must:
170+
- Add `"use memo"` to every component you want optimized
171+
- Add `"use memo"` to every custom hook
172+
- Remember to add it to new components
173+
174+
This gives you precise control over which components are compiled while you evaluate the compiler's impact.
175+
176+
## Runtime Feature Flags with Gating {/*runtime-feature-flags-with-gating*/}
177+
178+
The `gating` option enables you to control compilation at runtime using feature flags. This is useful for running A/B tests or gradually rolling out the compiler based on user segments.
179+
180+
### How Gating Works {/*how-gating-works*/}
181+
182+
The compiler wraps optimized code in a runtime check. If the gate returns `true`, the optimized version runs. Otherwise, the original code runs.
183+
184+
### Gating Configuration {/*gating-configuration*/}
185+
186+
```js
187+
// babel.config.js
188+
module.exports = {
189+
plugins: [
190+
['babel-plugin-react-compiler', {
191+
gating: {
192+
source: 'ReactCompilerFeatureFlags',
193+
importSpecifierName: 'isCompilerEnabled',
194+
},
195+
}],
196+
],
197+
};
198+
```
199+
200+
### Implementing the Feature Flag {/*implementing-the-feature-flag*/}
201+
202+
Create a module that exports your gating function:
203+
204+
```js
205+
// ReactCompilerFeatureFlags.js
206+
export function isCompilerEnabled() {
207+
// Use your feature flag system
208+
return getFeatureFlag('react-compiler-enabled');
209+
}
210+
```
211+
212+
## Troubleshooting Adoption {/*troubleshooting-adoption*/}
213+
214+
If you encounter issues during adoption:
215+
216+
1. Use `"use no memo"` to temporarily exclude problematic components
217+
2. Check the [debugging guide](/learn/react-compiler/debugging) for common issues
218+
3. Fix Rules of React violations identified by the ESLint plugin
219+
4. Consider using `compilationMode: 'annotation'` for more gradual adoption
220+
221+
## Next Steps {/*next-steps*/}
222+
223+
- Read the [configuration guide](/reference/react-compiler/configuration) for more options
224+
- Learn about [debugging techniques](/learn/react-compiler/debugging)
225+
- Check the [API reference](/reference/react-compiler/configuration) for all compiler options
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
title: React Compiler
3+
---
4+
5+
## Introduction {/*introduction*/}
6+
7+
Learn [what React Compiler does](/learn/react-compiler/introduction) and how it automatically optimizes your React application by handling memoization for you, eliminating the need for manual `useMemo`, `useCallback`, and `React.memo`.
8+
9+
## Installation {/*installation*/}
10+
11+
Get started with [installing React Compiler](/learn/react-compiler/installation) and learn how to configure it with your build tools.
12+
13+
14+
## Incremental Adoption {/*incremental-adoption*/}
15+
16+
Learn [strategies for gradually adopting React Compiler](/learn/react-compiler/incremental-adoption) in your existing codebase if you're not ready to enable it everywhere yet.
17+
18+
## Debugging and Troubleshooting {/*debugging-and-troubleshooting*/}
19+
20+
When things don't work as expected, use our [debugging guide](/learn/react-compiler/debugging) to understand the difference between compiler errors and runtime issues, identify common breaking patterns, and follow a systematic debugging workflow.
21+
22+
## Configuration and Reference {/*configuration-and-reference*/}
23+
24+
For detailed configuration options and API reference:
25+
26+
- [Configuration Options](/reference/react-compiler/configuration) - All compiler configuration options including React version compatibility
27+
- [Directives](/reference/react-compiler/directives) - Function-level compilation control
28+
- [Compiling Libraries](/reference/react-compiler/compiling-libraries) - Shipping pre-compiled libraries
29+
30+
## Additional resources {/*additional-resources*/}
31+
32+
In addition to these docs, we recommend checking the [React Compiler Working Group](https://github.com/reactwg/react-compiler) for additional information and discussion about the compiler.
33+

0 commit comments

Comments
 (0)