logo by @sawaratsuki1004
React
v19.2
Learn
Reference
Community
Blog

Is this page useful?

On this page

  • Overview
  • Why Incremental Adoption?
  • Approaches to Incremental Adoption
  • Directory-Based Adoption with Babel Overrides
  • Basic Configuration
  • Expanding Coverage
  • With Compiler Options
  • Opt-in Mode with “use memo”
  • Annotation Mode Configuration
  • Using the Directive
  • Runtime Feature Flags with Gating
  • How Gating Works
  • Gating Configuration
  • Implementing the Feature Flag
  • Troubleshooting Adoption
  • Next Steps

    GET STARTED

  • Quick Start
    • Tutorial: Tic-Tac-Toe
    • Thinking in React
  • Installation
    • Creating a React App
    • Build a React App from Scratch
    • Add React to an Existing Project
  • Setup
    • Editor Setup
    • Using TypeScript
    • React Developer Tools
  • React Compiler
    • Introduction
    • Installation
    • Incremental Adoption
    • Debugging and Troubleshooting
  • LEARN REACT

  • Describing the UI
    • Your First Component
    • Importing and Exporting Components
    • Writing Markup with JSX
    • JavaScript in JSX with Curly Braces
    • Passing Props to a Component
    • Conditional Rendering
    • Rendering Lists
    • Keeping Components Pure
    • Your UI as a Tree
  • Adding Interactivity
    • Responding to Events
    • State: A Component's Memory
    • Render and Commit
    • State as a Snapshot
    • Queueing a Series of State Updates
    • Updating Objects in State
    • Updating Arrays in State
  • Managing State
    • Reacting to Input with State
    • Choosing the State Structure
    • Sharing State Between Components
    • Preserving and Resetting State
    • Extracting State Logic into a Reducer
    • Passing Data Deeply with Context
    • Scaling Up with Reducer and Context
  • Escape Hatches
    • Referencing Values with Refs
    • Manipulating the DOM with Refs
    • Synchronizing with Effects
    • You Might Not Need an Effect
    • Lifecycle of Reactive Effects
    • Separating Events from Effects
    • Removing Effect Dependencies
    • Reusing Logic with Custom Hooks
Learn React
React Compiler

Incremental Adoption

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.

You will learn

  • Why incremental adoption is recommended
  • Using Babel overrides for directory-based adoption
  • Using the “use memo” directive for opt-in compilation
  • Using the “use no memo” directive to exclude components
  • Runtime feature flags with gating
  • Monitoring your adoption progress

Why Incremental Adoption?

React Compiler is designed to optimize your entire codebase automatically, but you don’t have to adopt it all at once. Incremental adoption gives you control over the rollout process, letting you test the compiler on small parts of your app before expanding to the rest.

Starting small helps you build confidence in the compiler’s optimizations. You can verify that your app behaves correctly with compiled code, measure performance improvements, and identify any edge cases specific to your codebase. This approach is especially valuable for production applications where stability is critical.

Incremental adoption also makes it easier to address any Rules of React violations the compiler might find. Instead of fixing violations across your entire codebase at once, you can tackle them systematically as you expand compiler coverage. This keeps the migration manageable and reduces the risk of introducing bugs.

By controlling which parts of your code get compiled, you can also run A/B tests to measure the real-world impact of the compiler’s optimizations. This data helps you make informed decisions about full adoption and demonstrates the value to your team.

Approaches to Incremental Adoption

There are three main approaches to adopt React Compiler incrementally:

  1. Babel overrides - Apply the compiler to specific directories
  2. Opt-in with “use memo” - Only compile components that explicitly opt in
  3. Runtime gating - Control compilation with feature flags

All approaches allow you to test the compiler on specific parts of your application before full rollout.

Directory-Based Adoption with Babel Overrides

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.

Basic Configuration

Start by applying the compiler to a specific directory:

// babel.config.js module.exports = { plugins: [ // Global plugins that apply to all files ], overrides: [ { test: './src/modern/**/*.{js,jsx,ts,tsx}', plugins: [ 'babel-plugin-react-compiler' ] } ] };

Expanding Coverage

As you gain confidence, add more directories:

// babel.config.js module.exports = { plugins: [ // Global plugins ], overrides: [ { test: ['./src/modern/**/*.{js,jsx,ts,tsx}', './src/features/**/*.{js,jsx,ts,tsx}'], plugins: [ 'babel-plugin-react-compiler' ] }, { test: './src/legacy/**/*.{js,jsx,ts,tsx}', plugins: [ // Different plugins for legacy code ] } ] };

With Compiler Options

You can also configure compiler options per override:

// babel.config.js module.exports = { plugins: [], overrides: [ { test: './src/experimental/**/*.{js,jsx,ts,tsx}', plugins: [ ['babel-plugin-react-compiler', { // options ... }] ] }, { test: './src/production/**/*.{js,jsx,ts,tsx}', plugins: [ ['babel-plugin-react-compiler', { // options ... }] ] } ] };

Opt-in Mode with “use memo”

For maximum control, you can use compilationMode: 'annotation' to only compile components and hooks that explicitly opt in with the "use memo" directive.

Note

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.

Annotation Mode Configuration

// babel.config.js module.exports = { plugins: [ ['babel-plugin-react-compiler', { compilationMode: 'annotation', }], ], };

Using the Directive

Add "use memo" at the beginning of functions you want to compile:

function TodoList({ todos }) { "use memo"; // Opt this component into compilation const sortedTodos = todos.slice().sort(); return ( <ul> {sortedTodos.map(todo => ( <TodoItem key={todo.id} todo={todo} /> ))} </ul> ); } function useSortedData(data) { "use memo"; // Opt this hook into compilation return data.slice().sort(); }

With compilationMode: 'annotation', you must:

  • Add "use memo" to every component you want optimized
  • Add "use memo" to every custom hook
  • Remember to add it to new components

This gives you precise control over which components are compiled while you evaluate the compiler’s impact.

Runtime Feature Flags with Gating

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.

How Gating Works

The compiler wraps optimized code in a runtime check. If the gate returns true, the optimized version runs. Otherwise, the original code runs.

Gating Configuration

// babel.config.js module.exports = { plugins: [ ['babel-plugin-react-compiler', { gating: { source: 'ReactCompilerFeatureFlags', importSpecifierName: 'isCompilerEnabled', }, }], ], };

Implementing the Feature Flag

Create a module that exports your gating function:

// ReactCompilerFeatureFlags.js export function isCompilerEnabled() { // Use your feature flag system return getFeatureFlag('react-compiler-enabled'); }

Troubleshooting Adoption

If you encounter issues during adoption:

  1. Use "use no memo" to temporarily exclude problematic components
  2. Check the debugging guide for common issues
  3. Fix Rules of React violations identified by the ESLint plugin
  4. Consider using compilationMode: 'annotation' for more gradual adoption

Next Steps

  • Read the configuration guide for more options
  • Learn about debugging techniques
  • Check the API reference for all compiler options
PreviousInstallation
NextDebugging and Troubleshooting

Copyright © Meta Platforms, Inc
no uwu plz
uwu?
Logo by@sawaratsuki1004
Learn React
Quick Start
Installation
Describing the UI
Adding Interactivity
Managing State
Escape Hatches
API Reference
React APIs
React DOM APIs
Community
Code of Conduct
Meet the Team
Docs Contributors
Acknowledgements
More
Blog
React Native
Privacy
Terms
// babel.config.js
module.exports = {
plugins: [
// Global plugins that apply to all files
],
overrides: [
{
test: './src/modern/**/*.{js,jsx,ts,tsx}',
plugins: [
'babel-plugin-react-compiler'
]
}
]
};
// babel.config.js
module.exports = {
plugins: [
// Global plugins
],
overrides: [
{
test: ['./src/modern/**/*.{js,jsx,ts,tsx}', './src/features/**/*.{js,jsx,ts,tsx}'],
plugins: [
'babel-plugin-react-compiler'
]
},
{
test: './src/legacy/**/*.{js,jsx,ts,tsx}',
plugins: [
// Different plugins for legacy code
]
}
]
};
// babel.config.js
module.exports = {
plugins: [],
overrides: [
{
test: './src/experimental/**/*.{js,jsx,ts,tsx}',
plugins: [
['babel-plugin-react-compiler', {
// options ...
}]
]
},
{
test: './src/production/**/*.{js,jsx,ts,tsx}',
plugins: [
['babel-plugin-react-compiler', {
// options ...
}]
]
}
]
};
// babel.config.js
module.exports = {
plugins: [
['babel-plugin-react-compiler', {
compilationMode: 'annotation',
}],
],
};
function TodoList({ todos }) {
"use memo"; // Opt this component into compilation

const sortedTodos = todos.slice().sort();

return (
<ul>
{sortedTodos.map(todo => (
<TodoItem key={todo.id} todo={todo} />
))}
</ul>
);
}

function useSortedData(data) {
"use memo"; // Opt this hook into compilation

return data.slice().sort();
}
// babel.config.js
module.exports = {
plugins: [
['babel-plugin-react-compiler', {
gating: {
source: 'ReactCompilerFeatureFlags',
importSpecifierName: 'isCompilerEnabled',
},
}],
],
};
// ReactCompilerFeatureFlags.js
export function isCompilerEnabled() {
// Use your feature flag system
return getFeatureFlag('react-compiler-enabled');
}