Skip to content

React Compiler

Fresh

React Compiler is a build-time tool that automatically optimizes your React application by handling memoization for you.

What React Compiler Does

React Compiler understands your code at a deep level through its understanding of plain JavaScript semantics and the Rules of React. This allows it to add automatic optimizations to your code.

When it detects violations of the Rules of React, it will automatically skip just those components or hooks and continue safely compiling other code.

INFO

React Compiler replaces manual useMemo, useCallback, and React.memo calls. If your code is already well-memoized, you might not see major performance improvements, but removing the manual memoization makes code cleaner.

The Rules of React

React Compiler enforces these rules:

  1. Components and Hooks must be pure - same inputs produce same outputs, no side effects during render
  2. Don't mutate props or state - always create new objects/arrays
  3. Hook call order must be stable - no hooks in conditions or loops
  4. Values passed to hooks are immutable after being passed
  5. JSX values are immutable after being created

Installation

bash
npm install -D babel-plugin-react-compiler

With Next.js

js
// next.config.js
module.exports = {
  experimental: {
    reactCompiler: true,
  },
};

With Vite

js
// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [
    react({
      babel: {
        plugins: [
          ['babel-plugin-react-compiler', {}],
        ],
      },
    }),
  ],
});

With Babel Directly

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

Incremental Adoption

You don't have to compile your entire codebase at once. Use the compilationMode option:

js
// Only compile components/hooks that explicitly opt in
['babel-plugin-react-compiler', {
  compilationMode: 'annotation',
}]

Then annotate components with the 'use memo' directive:

jsx
'use memo';

export default function MyComponent() {
  // This component will be compiled
}

Gating

Use the gating option for A/B testing the compiler's output:

js
['babel-plugin-react-compiler', {
  gating: {
    source: 'ReactCompilerFlag',
    importSpecifierName: 'isCompilerEnabled',
  },
}]

panicThreshold

Controls how the compiler handles code it cannot safely compile:

js
['babel-plugin-react-compiler', {
  panicThreshold: 'NONE', // skip all components on error (safest)
}]

Options:

  • 'NONE' - Skip component on any issue (default, safest)
  • 'CRITICAL_ERRORS' - Only skip on critical errors
  • 'ALL_ERRORS' - Never skip (not recommended)

ESLint Plugin

Install the ESLint plugin to catch Rules of React violations in your editor:

bash
npm install -D eslint-plugin-react-hooks@^6.0.0
js
// eslint.config.js
import reactHooksPlugin from 'eslint-plugin-react-hooks';

export default [
  {
    plugins: {
      'react-hooks': reactHooksPlugin,
    },
    rules: reactHooksPlugin.configs.recommended.rules,
  },
];

The plugin validates the Rules of React independently from the compiler, so you can use it even without the compiler.