The compiler is one development dependency and one line of build configuration:
npm install -D babel-plugin-react-compiler@latest eslint-plugin-react-hooks@latestIn a Vite 8 25,978 project, @vitejs/plugin-react 6.1.1 exposes the compiler as a Babel 41,624 preset that runs through @rolldown/plugin-babel:
import { defineConfig } from 'vite';
import react, { reactCompilerPreset } from '@vitejs/plugin-react';
import babel from '@rolldown/plugin-babel';
export default defineConfig({
plugins: [react(), babel({ presets: [reactCompilerPreset()] })],
});On older Vite the plugin goes straight to Babel instead, with react({ babel: { plugins: ['babel-plugin-react-compiler'] } }). In a plain Babel setup, 'babel-plugin-react-compiler' must be first in the plugins array, ahead of the JSX transform. Next.js 10,514 has its own switch, covered in Next.js.
The lint rules moved house in the 1.0 release: they now live in eslint-plugin-react-hooks 7.1.1 rather than the separate eslint-plugin-react-compiler, and the recommended-latest preset turns on both the Hook rules and the compiler's diagnostics — set-state-in-render, set-state-in-effect and refs among them. Lint first: every rule it reports is a place the compiler would have to decline.
| Option | What it controls | Typical value |
|---|---|---|
| compilationMode | Which functions get compiled | 'annotation' for opt-in |
| target | React 7,897 version to emit for | '17', '18' or '19' |
| panicThreshold | Code it cannot compile | 'none': skip, do not fail |
| gating | Runtime flag for a staged rollout | { source, importSpecifierName } |
| logger | Reporting of compiled files | logEvent(filename, event) |
A React 17 or 18 codebase works too: set target: '17' or '18' and add the react-compiler-runtime package, which supplies the c Hook that React 19 ships natively.
For an existing application, turn it on gradually. compilationMode: 'annotation' compiles only functions whose body starts with the "use memo" directive, so you convert a screen at a time; Babel's overrides option does the same by directory. In the other direction, "use no memo" as a function's first statement excludes it — its compiled output is byte-for-byte its input. A module-level directive covers the file; a function-level one wins.