How to Build Reusable React Components?
In order to gather early community feedback, we have made the new compiler React Compiler open source. Â It is a build-time tool that optimizes your React application automatically. Â You don’t need to alter any code to utilize it because it understands the Rules of React and works with standard JavaScript.
Additionally, the compiler comes with an ESLint plugin that displays the analysis directly in your editor. Everyone is encouraged to use the linter today. Â You can use the linter even if you are not yet ready to test out the compiler because it does not require that you have it installed.
You can test the compiler on React 17+ apps and libraries since it is presently available in beta form. To install the Beta:
npm install -D babel-plugin-react-compiler@beta eslint-plugin-react-compiler@beta
Or, if you’re using Yarn:
yarn add -D babel-plugin-react-compiler@beta eslint-plugin-react-compiler@beta
If you are not using React 19 yet, please see the section below for further instructions.
What compiler do?
React Compiler automatically memoizes your code to optimize applications. Â Memorization may be familiar to you now thanks to APIs like React.memo
, useMemo
, and useCallback
.  By using these APIs, you can reduce the amount of work required for updates by instructing React that some sections of your application don’t require recompute if their inputs haven’t changed.  Despite their strength, memoization techniques are simple to overlook or use improperly. This can lead to inefficient updates as React has to check parts of your UI that don’t have any meaningful changes.
Values or sets of values within your components and hooks are automatically memoized by the compiler using its understanding of JavaScript and React’s principles. Â It will automatically skip over only those parts or hooks and carry on securely compiling other code if it finds rule violations.
Note: When the Rules of React are violated, the React compiler may statically identify it and safely opt out of optimizing only the impacted hooks or components. Â The compiler does not have to optimize your entire codebase.
You might not anticipate significant compiler performance gains if your codebase is already highly memorized. Â However, it can be challenging to manually memoize the precise dependencies that lead to performance problems in practice.
Should I give the compiler a try?
Please be aware that there are many bugs and that the compiler is currently in beta. Â Rolling out the compiler to production for your project will rely on how well you’ve adhered to the Rules of React and how well your codebase is doing, even though it has been used in production at organizations like Meta.
You don’t need to use the compiler right now. Â Waiting for a stable release before embracing it is OK. Nevertheless, we would welcome it if you could test it out in tiny trials in your apps and give us feedback so we can improve the compiler.
Getting Started
For further information and discussion regarding the compiler, we suggest visiting the React Compiler Working Group in addition to these documents.
The eslint-plugin-react-compiler installation
An ESLint plugin is also powered by the React Compiler. You can use the ESLint plugin even if you don’t use the compiler because it can be used independently of it.
npm install -D eslint-plugin-react-compiler@beta
Then, add it to your ESLint config:
import reactCompiler from 'eslint-plugin-react-compiler'
export default [
{
plugins: {
'react-compiler': reactCompiler,
},
rules: {
'react-compiler/react-compiler': 'error',
},
},
]
Or, in the deprecated eslintrc config format:
module.exports = {
plugins: [
'eslint-plugin-react-compiler',
],
rules: {
'react-compiler/react-compiler': 'error',
},
}
Any React rules breaches will be shown in your editor by the ESLint plugin. Â This indicates that the compiler has omitted optimizing that hook or component. Â The compiler can recover and carry on optimizing other parts of your codebase, thus this is quite OK.
Note: You don’t have to immediately correct every ESLint infraction. Â It is not necessary to repair everything before using the compiler, but you can work on them at your own pace to increase the number of components and hooks being optimized.
Rolling out the compiler to your codebase
Existing projects
Compiling functional components and hooks that adhere to the React Rules is the purpose of the compiler. Â By bailing out (skipping over) those hooks or components, it can also handle code that violates those guidelines. The compiler may inadvertently build a component or hook that violates the Rules of React, which could result in undefined behavior, because JavaScript is so versatile that it is unable to detect every potential infraction.
Because of this, we advise using the compiler on a tiny directory within your product code initially in order to properly implement it on ongoing projects. This can be accomplished by setting the compiler to only execute on a particular collection of directories:
const ReactCompilerConfig = {
sources: (filename) => {
return filename.indexOf('src/path/to/dir') !== -1;
},
};
You can extend coverage to other folders and gradually roll it out to your entire application once you feel more comfortable deploying the compiler.
New Projects
The default behavior is to enable the compiler on your whole codebase when you start a new project.
Using React 17 or 18 with the React Compiler
React 19 RC is the ideal version for React Compiler. Â Installing the additional react-compiler-runtime
package will enable the compiled code to run on versions lower than 19 if you are unable to update. Â But take note that version 17 is the very minimum supported.
npm install react-compiler-runtime@beta
You should also add the correct target
to your compiler config, where target
is the major version of React you are targeting:
// babel.config.js
const ReactCompilerConfig = {
target: '18' // '17' | '18' | '19'
};
module.exports = function () {
return {
plugins: [
['babel-plugin-react-compiler', ReactCompilerConfig],
],
};
};
Using the compiler on libraries
Libraries can also be compiled using React Compiler. An application’s build pipeline cannot compile the libraries it uses because React Compiler must run on the original source code before any code modifications can occur. As a result, we advise library maintainers to use the compiler to independently compile and verify their libraries before sending the resultant code to npm.
Users of your library will be able to take use of the automated memoization that is applied to your library without having to enable the compiler because your code is pre-compiled. Add react-compiler-runtime as a direct dependency and set a minimum target if your library is intended for apps that are not yet using React 19. Depending on the version of the application, the runtime package will use the appropriate API implementation and, if required, polyfill the missing APIs.
More intricate patterns and the use of escape hatches are frequently needed in library programs. Â Because of this, we advise making sure you have enough testing to find any problems that might occur while using the compiler on your library. Â You can always use the 'use no memo'
directive to opt out of the particular hooks or components if you find any problems.
Like apps, you can experience benefits from your library without compiling all of your components or hooks. Â Finding the most performance-sensitive sections of your library and making sure they don’t violate the React Rules could be a smart place to start. You can do this with the eslint-plugin-react-compiler
.
Usage
Babel
npm install babel-plugin-react-compiler@beta
You can run the compiler in your build process by using the Babel plugin that comes with it.
Add it to your Babel configuration after installation. Please be aware that the compiler must execute in the pipeline first:
// babel.config.js
const ReactCompilerConfig = { /* ... */ };
module.exports = function () {
return {
plugins: [
['babel-plugin-react-compiler', ReactCompilerConfig], // must run first!
// ...
],
};
};
babel-plugin-react-compiler should run first before other Babel plugins as the compiler requires the input source information for sound analysis.
Vite:Â If you use Vite, you can add the plugin to vite-plugin-react:
// vite.config.js
const ReactCompilerConfig = { /* ... */ };
export default defineConfig(() => {
return {
plugins: [
react({
babel: {
plugins: [
["babel-plugin-react-compiler", ReactCompilerConfig],
],
},
}),
],
// ...
};
});
Next.js: Please refer to the Next.js docs for more data.
Remix: Install vite-plugin-babel, and add the compiler’s Babel plugin to it:
npm install vite-plugin-babel
// vite.config.js
import babel from "vite-plugin-babel";
const ReactCompilerConfig = { /* ... */ };
export default defineConfig({
plugins: [
remix({ /* ... */}),
babel({
filter: /\.[jt]sx?$/,
babelConfig: {
presets: ["@babel/preset-typescript"], // if you use TypeScript
plugins: [
["babel-plugin-react-compiler", ReactCompilerConfig],
],
},
}),
],
});
Webpack:Â There is now a community webpack loader available here.
Expo: To enable and utilize the React Compiler in Expo apps, please consult Expo’s documentation.
Metro (React Native): For installation instructions, see the Usage with Babel section. React Native uses Babel via Metro.
Rspack: To enable and utilize the React Compiler in Rspack apps, please see the documentation provided by Rspack.
Rsbuild:Â To enable and utilize the React Compiler in Rsbuild apps, please see the documentation provided by Rsbuild.
Troubleshooting
Please make a small repro on the React Compiler Playground before reporting problems, then attach it to your bug report. Â Issues can be opened on the Facebook/React repository.
By submitting an application to join the React Compiler Working Group, you can also offer input. To learn more about joining, please go to the README.
What does the compiler assume?
React Compiler assumes that your code:
1. JavaScript is valid and semantic.
2. if (object.nullableProperty)
{ object.nullableProperty.foo } or with optional-chaining object.nullableProperty?.foo, which checks if nullable/optional values and properties are defined before accessing them (for instance, by turning on strictNullChecks
if using TypeScript).
3. complies with the React Rules.
When it discovers a mistake, the React Compiler will safely skip compilation and can statically validate several of the React Rules. Â We also advise installing eslint-plugin-react-compiler in order to view the errors.
How can I tell whether my parts have been optimized?
React Compiler is integrated into React DevTools (v5.0+) and React Native DevTools, which will show a “Memo” badge next to compiler-optimized components.
After compilation, something is not functioning.
Any infractions of the React rules will be shown in your editor by the compiler if you have eslint-plugin-react-compiler installed. This indicates that the compiler has omitted optimizing that hook or component. The compiler can recover and carry on optimizing other parts of your codebase, thus this is quite OK. You don’t have to immediately correct every ESLint infraction. To expand the number of components and hooks being optimized, you can work on them at your own pace.
However, because JavaScript is dynamic and versatile, it is impossible to fully detect every scenario. In those situations, bugs and undefinable behavior, including infinite loops, could appear.
The compiler might be building your code erroneously if your application doesn’t function correctly after compilation and you don’t see any ESLint errors. Â To verify this, use the "use no memo"
directive to aggressively opt out each component or hook you believe may be connected in an attempt to resolve the issue.
function SuspiciousComponent() {
"use no memo"; // opts out this component from being compiled by React Compiler
// ...
}
Note:
You can temporarily avoid the React Compiler from compiling components and hooks by using the "use no memo" escape hatch. Â This command isn't intended to last as long as, say, "use client."
Verify that deleting the opt-out directive causes the problem to reappear after you have fixed the fault. Then, using the React Compiler Playground, submit a bug report to us. If the code is open source, you may just paste the complete source or attempt to reduce it to a short repro so we can find and assist in fixing the problem.
Ready to take the first step towards unlocking opportunities, realizing goals, and embracing innovation? We're here and eager to connect.