Skip to main content

How to Enable React Compiler in Your Project

Enabling the React Compiler in your project takes 5-10 minutes and requires only one npm package and a few lines of configuration. I've set it up in projects ranging from small Vite apps to large Next.js monorepos, and the process is consistent and straightforward.

Prerequisites

  • Node.js 18+
  • React 19+
  • Build tool: Vite, Create React App (via eject or custom setup), or Next.js 15+
  • Optional: TypeScript (compiler supports both JS and TS)

Installation: All Frameworks

First, install the compiler package:

npm install --save-dev babel-plugin-react-compiler

Or with yarn/pnpm:

yarn add --dev babel-plugin-react-compiler
pnpm add -D babel-plugin-react-compiler

The package is a Babel plugin, so your build tool must use Babel (Vite and CRA do by default; Next.js has it built-in).

Setup for Vite Projects

Vite uses Babel for JSX transformation. Create or update babel.config.js in your project root:

export default {
presets: [['@babel/preset-react', { runtime: 'automatic' }]],
plugins: ['babel-plugin-react-compiler'],
};

Then run your dev server:

npm run dev

Vite automatically picks up the Babel config. Watch for a console message like: [React Compiler] compiled Component1, Component2, ... confirming the plugin is active.

Setup for Create React App (After Eject)

If you've ejected from CRA, update config/webpack.config.js to add the plugin to the babel-loader configuration:

{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-react', { runtime: 'automatic' }],
['@babel/preset-env', { targets: { browsers: ['last 2 versions'] } }],
],
plugins: ['babel-plugin-react-compiler'],
},
},
}

If you haven't ejected, consider ejecting (npm run eject) or switching to Vite, as CRA doesn't expose Babel configuration without eject.

Setup for Next.js 15+

Next.js 15+ includes built-in support for the React Compiler. Just add it to next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
reactCompiler: true,
},
};

module.exports = nextConfig;

That's it. Next.js handles all Babel configuration internally.

Setup for TypeScript Projects

No special configuration needed. The compiler works identically with .tsx files. Just ensure your tsconfig.json includes "jsx": "react-jsx":

{
"compilerOptions": {
"jsx": "react-jsx",
"target": "ES2020"
}
}

Verification: Is the Compiler Running?

Add a test component to confirm the compiler is active. Check your browser console or build output:

function TestComponent() {
const [count, setCount] = useState(0);
console.log("Compiled with React Compiler" + (count > 0 ? "" : " (first render)"));
return <button onClick={() => setCount(count + 1)}>Clicks: {count}</button>;
}

Run your build or dev server. If the compiler is active, you should see compiler log output during the build phase. In Vite, watch for a console message like:

[React Compiler] Compiled 42 components

In Next.js, check the build output:

react compiler: 127 components compiled, 0 bailouts

If you see no output, double-check your Babel or Next.js configuration.

Configuration Options

The React Compiler supports a few options via Babel:

plugins: [
[
'babel-plugin-react-compiler',
{
target: '19', // React version (18 or 19)
passthroughMarker: '__NEVER_OPTIMIZE__', // Mark functions to skip compilation
environment: 'production', // 'production' or 'development'
},
],
],
  • target: Set to '19' for React 19, '18' for React 18 compatibility.
  • passthroughMarker: Functions marked with this comment won't be optimized (useful for library code or unsafe patterns).
  • environment: Use 'production' for deployments; 'development' skips some optimizations for faster builds during development.

Handling Bailouts: Opt-Out for Specific Components

If the compiler can't optimize a component (e.g., it uses unsafe patterns), it will "bail out." You can explicitly mark components to skip compilation:

// @babel-ignore-next-line
const UnstableComponent = ({ prop }) => {
// This component won't be compiled
return <div>{prop}</div>;
};

// Or use the passthroughMarker comment:
function AnotherUnsafe() {
// __NEVER_OPTIMIZE__
return <div>Not compiled</div>;
}

Use this sparingly—only when you have code the compiler can't handle safely.

Debugging: Enable Verbose Logging

To see which components are compiled and which bail out, enable verbose logging in your Babel config:

plugins: [
[
'babel-plugin-react-compiler',
{
target: '19',
__debug: true, // Verbose logging
},
],
],

During build, you'll see output like:

[React Compiler] > app/page.tsx
✓ UserProfile (deps: [userId])
✗ UnstablePicker (bailout: mutable default param)

The means compiled; means bailed out with a reason.

Incremental Rollout: Per-Directory Compilation

For large projects, you can enable the compiler for specific directories. Use different Babel configs in Vite's vite.config.js:

export default {
plugins: [
{
...viteBabelPlugin({
include: /src\/new-feature\/.+\.tsx?$/,
plugins: ['babel-plugin-react-compiler'],
}),
},
],
};

This compiles only files under src/new-feature/, allowing gradual rollout.

Key Takeaways

  • Installing babel-plugin-react-compiler and adding it to your Babel or Next.js config is all that's needed.
  • Vite, Next.js, and ejected CRA all support the compiler with minimal configuration.
  • Verify the compiler is running by checking build output for compilation messages.
  • Use opt-out markers (@babel-ignore-next-line) for code the compiler can't handle.
  • Enable __debug: true to see which components are compiled and which bail out.

Frequently Asked Questions

Will enabling the compiler break my existing code?

No. The compiler is backward-compatible. It generates code semantically equivalent to your original; if it can't optimize something, it passes through the original code unchanged.

Can I disable the compiler for production and keep it for development?

The opposite is recommended: use the compiler for production (where performance matters most) and optionally disable it for faster development builds by setting environment: 'development'.

Do I need to restart my dev server after enabling the compiler?

Yes. Restart the dev server (or webpack dev server in CRA) so Babel reloads its configuration.

What if my build fails after enabling the compiler?

Check the error message. Common issues: (1) babel-plugin-react-compiler not installed, (2) wrong Babel configuration path, (3) incompatible Babel versions. Run npm list babel-plugin-react-compiler to verify installation and check your build tool's Babel documentation.

Does the compiler work with Remix or Astro?

Remix uses Vite or esbuild; use the Vite setup above. Astro has experimental support; check the latest Astro docs for configuration steps.

Further Reading