Skip to content

Commit 9bf5003

Browse files
merging all conflicts
2 parents 1bfaba9 + 47e64bf commit 9bf5003

2 files changed

Lines changed: 363 additions & 0 deletions

File tree

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
---
2+
title: Installation
3+
---
4+
5+
<Intro>
6+
This guide will help you install and configure React Compiler in your React application.
7+
</Intro>
8+
9+
<YouWillLearn>
10+
11+
* How to install React Compiler
12+
* Basic configuration for different build tools
13+
* How to verify your setup is working
14+
15+
</YouWillLearn>
16+
17+
## Prerequisites {/*prerequisites*/}
18+
19+
React Compiler is designed to work best with React 19, but it also supports React 17 and 18. Learn more about [React version compatibility](/reference/react-compiler/target).
20+
21+
## Installation {/*installation*/}
22+
23+
Install React Compiler as a `devDependency`:
24+
25+
<TerminalBlock>
26+
npm install -D babel-plugin-react-compiler@latest
27+
</TerminalBlock>
28+
29+
Or with Yarn:
30+
31+
<TerminalBlock>
32+
yarn add -D babel-plugin-react-compiler@latest
33+
</TerminalBlock>
34+
35+
Or with pnpm:
36+
37+
<TerminalBlock>
38+
pnpm install -D babel-plugin-react-compiler@latest
39+
</TerminalBlock>
40+
41+
## Basic Setup {/*basic-setup*/}
42+
43+
React Compiler is designed to work by default without any configuration. However, if you need to configure it in special circumstances (for example, to target React versions below 19), refer to the [compiler options reference](/reference/react-compiler/configuration).
44+
45+
The setup process depends on your build tool. React Compiler includes a Babel plugin that integrates with your build pipeline.
46+
47+
<Pitfall>
48+
React Compiler must run **first** in your Babel plugin pipeline. The compiler needs the original source information for proper analysis, so it must process your code before other transformations.
49+
</Pitfall>
50+
51+
### Babel {/*babel*/}
52+
53+
Create or update your `babel.config.js`:
54+
55+
```js {3}
56+
module.exports = {
57+
plugins: [
58+
'babel-plugin-react-compiler', // must run first!
59+
// ... other plugins
60+
],
61+
// ... other config
62+
};
63+
```
64+
65+
### Vite {/*vite*/}
66+
67+
If you use Vite with version 6.0.0 or later of `@vitejs/plugin-react`, you can use the `reactCompilerPreset`:
68+
69+
<TerminalBlock>
70+
npm install -D @rolldown/plugin-babel
71+
</TerminalBlock>
72+
73+
```js {3-4,9-11}
74+
// vite.config.js
75+
import { defineConfig } from 'vite';
76+
import react, { reactCompilerPreset } from '@vitejs/plugin-react';
77+
import babel from '@rolldown/plugin-babel';
78+
79+
export default defineConfig({
80+
plugins: [
81+
react(),
82+
babel({
83+
presets: [reactCompilerPreset()]
84+
}),
85+
],
86+
});
87+
```
88+
89+
<Note>
90+
In `@vitejs/plugin-react@6.0.0`, the inline Babel option was removed. If you're using an older version, you can use:
91+
92+
```js
93+
// vite.config.js
94+
import { defineConfig } from 'vite';
95+
import react from '@vitejs/plugin-react';
96+
97+
export default defineConfig({
98+
plugins: [
99+
react({
100+
babel: {
101+
plugins: ['babel-plugin-react-compiler'],
102+
},
103+
}),
104+
],
105+
});
106+
```
107+
</Note>
108+
109+
Alternatively, you can use the Babel plugin directly with `@rolldown/plugin-babel`:
110+
111+
```js {3,9}
112+
// vite.config.js
113+
import { defineConfig } from 'vite';
114+
import react from '@vitejs/plugin-react';
115+
import babel from '@rolldown/plugin-babel';
116+
117+
export default defineConfig({
118+
plugins: [
119+
react(),
120+
babel({
121+
plugins: ['babel-plugin-react-compiler'],
122+
}),
123+
],
124+
});
125+
```
126+
127+
### Next.js {/*usage-with-nextjs*/}
128+
129+
Please refer to the [Next.js docs](https://nextjs.org/docs/app/api-reference/next-config-js/reactCompiler) for more information.
130+
131+
### React Router {/*usage-with-react-router*/}
132+
Install `vite-plugin-babel`, and add the compiler's Babel plugin to it:
133+
134+
<TerminalBlock>
135+
npm install vite-plugin-babel
136+
</TerminalBlock>
137+
138+
```js {3-4,16}
139+
// vite.config.js
140+
import { defineConfig } from "vite";
141+
import babel from "vite-plugin-babel";
142+
import { reactRouter } from "@react-router/dev/vite";
143+
144+
const ReactCompilerConfig = { /* ... */ };
145+
146+
export default defineConfig({
147+
plugins: [
148+
reactRouter(),
149+
babel({
150+
filter: /\.[jt]sx?$/,
151+
babelConfig: {
152+
presets: ["@babel/preset-typescript"], // if you use TypeScript
153+
plugins: [
154+
["babel-plugin-react-compiler", ReactCompilerConfig],
155+
],
156+
},
157+
}),
158+
],
159+
});
160+
```
161+
162+
### Webpack {/*usage-with-webpack*/}
163+
164+
A community webpack loader is [now available here](https://github.com/SukkaW/react-compiler-webpack).
165+
166+
### Expo {/*usage-with-expo*/}
167+
168+
Please refer to [Expo's docs](https://docs.expo.dev/guides/react-compiler/) to enable and use the React Compiler in Expo apps.
169+
170+
### Metro (React Native) {/*usage-with-react-native-metro*/}
171+
172+
React Native uses Babel via Metro, so refer to the [Usage with Babel](#babel) section for installation instructions.
173+
174+
### Rspack {/*usage-with-rspack*/}
175+
176+
Please refer to [Rspack's docs](https://rspack.dev/guide/tech/react#react-compiler) to enable and use the React Compiler in Rspack apps.
177+
178+
### Rsbuild {/*usage-with-rsbuild*/}
179+
180+
Please refer to [Rsbuild's docs](https://rsbuild.dev/guide/framework/react#react-compiler) to enable and use the React Compiler in Rsbuild apps.
181+
182+
183+
## ESLint Integration {/*eslint-integration*/}
184+
185+
React Compiler includes an ESLint rule that helps identify code that can't be optimized. When the ESLint rule reports an error, it means the compiler will skip optimizing that specific component or hook. This is safe: the compiler will continue optimizing other parts of your codebase. You don't need to fix all violations immediately. Address them at your own pace to gradually increase the number of optimized components.
186+
187+
Install the ESLint plugin:
188+
189+
<TerminalBlock>
190+
npm install -D eslint-plugin-react-hooks@latest
191+
</TerminalBlock>
192+
193+
If you haven't already configured eslint-plugin-react-hooks, follow the [installation instructions in the readme](https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/README.md#installation). The compiler rules are available in the `recommended-latest` preset.
194+
195+
The ESLint rule will:
196+
- Identify violations of the [Rules of React](/reference/rules)
197+
- Show which components can't be optimized
198+
- Provide helpful error messages for fixing issues
199+
200+
## Verify Your Setup {/*verify-your-setup*/}
201+
202+
After installation, verify that React Compiler is working correctly.
203+
204+
### Check React DevTools {/*check-react-devtools*/}
205+
206+
Components optimized by React Compiler will show a "Memo ✨" badge in React DevTools:
207+
208+
1. Install the [React Developer Tools](/learn/react-developer-tools) browser extension
209+
2. Open your app in development mode
210+
3. Open React DevTools
211+
4. Look for the ✨ emoji next to component names
212+
213+
If the compiler is working:
214+
- Components will show a "Memo ✨" badge in React DevTools
215+
- Expensive calculations will be automatically memoized
216+
- No manual `useMemo` is required
217+
218+
### Check Build Output {/*check-build-output*/}
219+
220+
You can also verify the compiler is running by checking your build output. The compiled code will include automatic memoization logic that the compiler adds automatically.
221+
222+
```js
223+
import { c as _c } from "react/compiler-runtime";
224+
export default function MyApp() {
225+
const $ = _c(1);
226+
let t0;
227+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
228+
t0 = <div>Hello World</div>;
229+
$[0] = t0;
230+
} else {
231+
t0 = $[0];
232+
}
233+
return t0;
234+
}
235+
236+
```
237+
238+
## Troubleshooting {/*troubleshooting*/}
239+
240+
### Opting out specific components {/*opting-out-specific-components*/}
241+
242+
If a component is causing issues after compilation, you can temporarily opt it out using the `"use no memo"` directive:
243+
244+
```js
245+
function ProblematicComponent() {
246+
"use no memo";
247+
// Component code here
248+
}
249+
```
250+
251+
This tells the compiler to skip optimization for this specific component. You should fix the underlying issue and remove the directive once resolved.
252+
253+
For more troubleshooting help, see the [debugging guide](/learn/react-compiler/debugging).
254+
255+
## Next Steps {/*next-steps*/}
256+
257+
Now that you have React Compiler installed, learn more about:
258+
259+
- [React version compatibility](/reference/react-compiler/target) for React 17 and 18
260+
- [Configuration options](/reference/react-compiler/configuration) to customize the compiler
261+
- [Incremental adoption strategies](/learn/react-compiler/incremental-adoption) for existing codebases
262+
- [Debugging techniques](/learn/react-compiler/debugging) for troubleshooting issues
263+
- [Compiling Libraries guide](/reference/react-compiler/compiling-libraries) for compiling your React library

src/content/reference/react/useOptimistic.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,108 @@ function AppContainer() {
5656

5757
#### Returns {/*returns*/}
5858

59+
<<<<<<< HEAD
5960
* `optimisticState`: The resulting optimistic state. It is equal to `state` unless an action is pending, in which case it is equal to the value returned by `updateFn`.
6061
* `addOptimistic`: `addOptimistic` is the dispatching function to call when you have an optimistic update. It takes one argument, `optimisticValue`, of any type and will call the `updateFn` with `state` and `optimisticValue`.
62+
=======
63+
`useOptimistic` returns an array with exactly two values:
64+
65+
1. `optimisticState`: The current optimistic state. It is equal to `value` unless an Action is pending, in which case it is equal to the state returned by `reducer` (or the value passed to the set function if no `reducer` was provided).
66+
2. The [`set` function](#setoptimistic) that lets you update the optimistic state to a different value inside an Action.
67+
68+
---
69+
70+
### `set` functions, like `setOptimistic(optimisticState)` {/*setoptimistic*/}
71+
72+
The `set` function returned by `useOptimistic` lets you update the state for the duration of an [Action](reference/react/useTransition#functions-called-in-starttransition-are-called-actions). You can pass the next state directly, or a function that calculates it from the previous state:
73+
74+
```js
75+
const [optimisticLike, setOptimisticLike] = useOptimistic(false);
76+
const [optimisticSubs, setOptimisticSubs] = useOptimistic(subs);
77+
78+
function handleClick() {
79+
startTransition(async () => {
80+
setOptimisticLike(true);
81+
setOptimisticSubs(a => a + 1);
82+
await saveChanges();
83+
});
84+
}
85+
```
86+
87+
#### Parameters {/*setoptimistic-parameters*/}
88+
89+
* `optimisticState`: The value that you want the optimistic state to be during an [Action](reference/react/useTransition#functions-called-in-starttransition-are-called-actions). If you provided a `reducer` to `useOptimistic`, this value will be passed as the second argument to your reducer. It can be a value of any type.
90+
* If you pass a function as `optimisticState`, it will be treated as an _updater function_. It must be pure, should take the pending state as its only argument, and should return the next optimistic state. React will put your updater function in a queue and re-render your component. During the next render, React will calculate the next state by applying the queued updaters to the previous state similar to [`useState` updaters](/reference/react/useState#setstate-parameters).
91+
92+
#### Returns {/*setoptimistic-returns*/}
93+
94+
`set` functions do not have a return value.
95+
96+
#### Caveats {/*setoptimistic-caveats*/}
97+
98+
* The `set` function must be called inside an [Action](reference/react/useTransition#functions-called-in-starttransition-are-called-actions). If you call the setter outside an Action, [React will show a warning](#an-optimistic-state-update-occurred-outside-a-transition-or-action) and the optimistic state will briefly render.
99+
100+
<DeepDive>
101+
102+
#### How optimistic state works {/*how-optimistic-state-works*/}
103+
104+
`useOptimistic` lets you show a temporary value while an Action is in progress:
105+
106+
```js
107+
const [value, setValue] = useState('a');
108+
const [optimistic, setOptimistic] = useOptimistic(value);
109+
110+
startTransition(async () => {
111+
setOptimistic('b');
112+
const newValue = await saveChanges('b');
113+
setValue(newValue);
114+
});
115+
```
116+
117+
When the setter is called inside an Action, `useOptimistic` will trigger a re-render to show that state while the Action is in progress. Otherwise, the `value` passed to `useOptimistic` is returned.
118+
119+
This state is called the "optimistic" because it is used to immediately present the user with the result of performing an Action, even though the Action actually takes time to complete.
120+
121+
**How the update flows**
122+
123+
1. **Update immediately**: When `setOptimistic('b')` is called, React immediately renders with `'b'`.
124+
125+
2. **(Optional) await in Action**: If you await in the Action, React continues showing `'b'`.
126+
127+
3. **Transition scheduled**: `setValue(newValue)` schedules an update to the real state.
128+
129+
4. **(Optional) wait for Suspense**: If `newValue` suspends, React continues showing `'b'`.
130+
131+
5. **Single render commit**: Finally, the `newValue` commits for `value` and `optimistic`.
132+
133+
There's no extra render to "clear" the optimistic state. The optimistic and real state converge in the same render when the Transition completes.
134+
135+
<Note>
136+
137+
#### Optimistic state is temporary {/*optimistic-state-is-temporary*/}
138+
139+
Optimistic state only renders while an Action is in progress, otherwise `value` is rendered.
140+
141+
If `saveChanges` returned `'c'`, then both `value` and `optimistic` will be `'c'`, not `'b'`.
142+
143+
</Note>
144+
145+
**How the final state is determined**
146+
147+
The `value` argument to `useOptimistic` determines what displays after the Action finishes. How this works depends on the pattern you use:
148+
149+
- **Hardcoded values** like `useOptimistic(false)`: After the Action, `state` is still `false`, so the UI shows `false`. This is useful for pending states where you always start from `false`.
150+
151+
- **Props or state passed in** like `useOptimistic(isLiked)`: If the parent updates `isLiked` during the Action, the new value is used after the Action completes. This is how the UI reflects the result of the Action.
152+
153+
- **Reducer pattern** like `useOptimistic(items, fn)`: If `items` changes while the Action is pending, React re-runs your `reducer` with the new `items` to recalculate the state. This keeps your optimistic additions on top of the latest data.
154+
155+
**What happens when the Action fails**
156+
157+
If the Action throws an error, the Transition still ends, and React renders with whatever `value` currently is. Since the parent typically only updates `value` on success, a failure means `value` hasn't changed, so the UI shows what it showed before the optimistic update. You can catch the error to show a message to the user.
158+
159+
</DeepDive>
160+
>>>>>>> 47e64bf7ad81aab8bacfa791a37816ee869135eb
61161
62162
---
63163

0 commit comments

Comments
 (0)