|
| 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 |
0 commit comments