Back to BlogReact

React Compiler 1.0: Say Goodbye to useMemo and useCallback (For Real This Time)

React Compiler 1.0 is stable and it automatically handles all your memoization so you don't have to. Here's how to set it up, what to remove, and whether it's ready for your production app.

ReactReact CompilerMemoizationPerformanceJavaScript
React Compiler 1.0: Say Goodbye to useMemo and useCallback (For Real This Time)

If you've been writing React for any amount of time, you've probably had that moment — staring at a component tree wondering "should this be wrapped in useMemo?" or "do I actually need this useCallback here?" It's a mental overhead that React devs have been dealing with for years. Manual memoization is one of those things that's technically optional, but practically mandatory the moment your app gets non-trivial.

React Compiler 1.0 went stable in October 2025, and it's designed to fix this whole problem at the compiler level. No more guessing, no more lint rules nagging you about missing deps, no more wrapping everything in memo just in case. The compiler does it for you, automatically, at build time.

So — is it actually ready for your production app? What do you need to know before you adopt it? Let's get into it.

What Is React Compiler and Why Should You Care?

React Compiler (previously called "React Forget" — love the branding) is a build-time tool from the React team at Meta. Instead of you manually telling React what to cache and when, the compiler analyzes your component code during the build step and automatically inserts optimized memoization logic.

The result: React only re-renders components when their data actually changes. Not when the parent re-renders. Not when an unrelated piece of state updates. Only when it needs to.

Without the compiler, you reach for these three APIs when performance gets bad:

  • useMemo for caching expensive computed values

  • useCallback for stable function references passed as props

  • React.memo for wrapping entire components to skip re-renders

React Compiler handles all three. Automatically. Without touching a single line of your component code.

How It Actually Works Under the Hood

React Compiler performs static analysis on your component code during the build step. It figures out which values are mutable vs stable, builds a dependency graph, and determines which renders can safely be skipped. Then it generates optimized code — so by the time your app ships, the memoization logic is already baked into the bundle.

Here's a simple example. You write clean, idiomatic React:

function ProductCard({ product, onAddToCart }) {
  const discountedPrice = product.price * 0.9;
  return (
    <div>
      <h2>{product.name}</h2>
      <p>${discountedPrice.toFixed(2)}</p>
      <button onClick={onAddToCart}>Add to Cart</button>
    </div>
  );
}

The compiler transforms this into something conceptually equivalent to wrapping the whole thing in React.memo, memoizing discountedPrice with useMemo, and stabilizing onAddToCart with useCallback — all based on what it can statically prove about your code's data flow. You never write a single memo call.

The key difference from manual memoization? The compiler can handle conditional paths, nested ternaries, and complex data flows that are basically impossible to manually optimize correctly without introducing bugs.

Setting It Up (Takes About 5 Minutes)

With Vite

Install the Babel plugin:

npm install -D babel-plugin-react-compiler

Then wire it up in vite.config.ts:

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

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

With Next.js

Even simpler — just flip the flag in next.config.ts:

const nextConfig = {
  experimental: {
    reactCompiler: true,
  },
};

export default nextConfig;

That's it. No component changes, no refactoring, no new APIs to learn. Just flip the switch and your whole app benefits. If you're on Expo, you don't even need to do this — React Compiler is enabled by default starting in Expo SDK 54.

What You Can (and Can't) Remove From Your Codebase

Once the compiler is running, you can start cleaning up manual memoization. But don't just delete everything blindly.

Generally safe to remove:

  • useMemo wrapping derived values computed from props or state

  • useCallback on event handlers passed to child components

  • React.memo() wrappers on most components — the compiler applies the equivalent automatically

Keep these around:

  • useMemo when creating class instances or objects needing referential stability for non-React reasons (e.g., a chart library that diffs by reference)

  • React.memo with a custom comparator when you have intentional update-blocking logic

  • useCallback when the function is passed directly to a native DOM API like addEventListener (outside React's tree)

When the Compiler Backs Off (and What To Do)

React Compiler isn't magic — it has a contract with you called the Rules of React. If your code breaks those rules, the compiler skips optimizing that component and leaves it as-is. The main gotchas:

  • Mutating props or state directly

  • Reading from external mutable state during render without going through a hook

  • Reading ref.current during render (it's a no-no)

  • Third-party libraries that internally violate React's rules

Before enabling the compiler on an existing project, run the ESLint plugin to audit your codebase first:

npm install -D eslint-plugin-react-compiler

It'll flag every component the compiler would skip, so you know exactly what to fix. You can also use compilationMode: "annotation" to opt in specific components one at a time with a 'use memo'; directive — great for a phased rollout on larger codebases.

Real-World Performance Numbers

Meta has been running React Compiler on Instagram, Facebook, and Quest for over a year. Their reported numbers:

  • 20-30% reduction in render time on major surfaces

  • Up to 12% faster initial page loads

  • Some interactions up to 2.5x faster

Those are big numbers. And keep in mind — Meta's codebases are not perfectly optimized React. The compiler finds and fixes patterns that no human reviewer would ever catch at scale.

Should You Adopt It Today?

  • New project on React 19+? Yes, enable it from day one. Zero downside, free performance.

  • Existing project on React 19? Run the ESLint plugin audit first, fix violations, then flip the switch. Use annotation mode for a phased rollout.

  • Still on React 18 or older? Upgrade first — React Compiler requires React 19. Add the upgrade to your backlog now.

The one thing I'd say: don't wait for a performance problem to justify adopting this. The whole point is that it prevents performance problems from accumulating in the first place. Enable it, clean up the manual memoization debt, and stop thinking about this class of problem entirely.

TL;DR

  • React Compiler 1.0 is stable and production-ready (Oct 2025)

  • It automatically handles useMemo, useCallback, and React.memo at build time

  • Works with Vite, Next.js, and Expo (enabled by default in SDK 54+)

  • Requires React 19 and adherence to the Rules of React

  • Run eslint-plugin-react-compiler to audit before enabling on existing projects

  • Meta reports 20-30% render time reduction on production apps — it's the real deal