KahWee - Web Development, AI Tools & Tech Trends

Expert takes on AI tools like Claude and Sora, modern web development with React and Vite, and tech trends. By KahWee.

React Compiler 1.0 - You Can Delete Your useCallback Hooks Now

React released Compiler 1.0 in October, and it might be the most boring-sounding update with the biggest real-world impact. Automatic memoization means you can delete most of your React.memo, useCallback, and useMemo calls. The compiler does it for you—and does it better than you were doing manually.

This isn't vaporware. Next.js 16 (also October) made Turbopack the default bundler with 2-5x faster builds. Bun 1.3 shipped full-stack runtime support. The entire React ecosystem just got a major performance upgrade without requiring you to rewrite anything.

What Actually Changed

Before: You wrapped components in React.memo, dependencies in useCallback, and expensive calculations in useMemo to prevent unnecessary re-renders. You probably forgot to do it half the time, and when you did remember, you had to maintain those dependency arrays.

After: The React Compiler analyzes your code and automatically memoizes values used in rendering. It's more granular than manual memoization—it can even memoize conditionally, which you couldn't do by hand.

Here's the practical difference. This code:

function Form({ onSubmit, onMount }) {
  // your component logic
}

Now automatically behaves as if you'd wrapped onSubmit and onMount in useCallback and Form in React.memo. Except you didn't have to do anything. The compiler handles it during the build process.

You write cleaner code. The compiler catches edge cases you'd miss. Same philosophy as TypeScript—let the tooling do the work.

When You Still Need Manual Memoization

One place: useEffect dependencies. If you're passing a value to useEffect and want to control when it runs, wrap it in useMemo. That's about it.

The official React blog explains this: manual memoization guarantees reference stability for effect dependencies, ensuring the effect only runs when the dependency meaningfully changes, not on every render.

Setting It Up

React Compiler requires React 19+. For older versions (17 or 18), you'll also need react-compiler-runtime@latest.

With Next.js

Next.js 16 made this dead simple. The compiler is already integrated. Just update your config:

// next.config.js
const nextConfig = {
  experimental: {
    reactCompiler: true,
  },
};

That's it. Next.js handles the Babel plugin setup automatically.

With Vite

Vite users need to add the Babel plugin manually since Vite uses esbuild by default. The trade-off: you get automatic memoization but add Babel overhead to your build.

Install the compiler:

npm install babel-plugin-react-compiler@latest

Add it to your Vite config:

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

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

The React Compiler must run first in your Babel plugin pipeline. The @vitejs/plugin-react handles this automatically when you configure it this way.

One thing to know: Vite without plugins uses pure esbuild for builds, which is extremely fast. Adding the React Compiler introduces Babel into the pipeline, which is slower. For most projects, the runtime performance gains from automatic memoization outweigh the build time cost. But if you're on a huge codebase where build time is critical, test both scenarios.

The Vite team is working with the oxc team to add native support for the compiler. Once that ships (and when Rolldown officially releases in Vite), you'll get automatic memoization without the Babel overhead. The React docs will update with migration info when that happens.

The Tooling Side

Next.js 16 shipped in October with Turbopack as the default bundler. Vercel's running production sites on it (vercel.com, v0.app, nextjs.org). Their benchmarks show 2-5x faster builds depending on project size.

Fast Refresh is about 10x quicker with Turbopack. That's the difference between "I'll grab coffee while this rebuilds" and "oh, it's already done."

Next.js 15.5 (August) had Turbopack in beta. By October it was stable enough to become the default. That's confidence.

Bun 1.3 added full-stack runtime support and can now compile entire apps into standalone binaries. Not directly related to React Compiler, but it's part of the same trend: tools getting faster without requiring you to change how you write code.

Why This Matters

The shift from manual optimization to automatic optimization is huge. You're not wrapping everything in memo wrappers anymore. Your codebase is cleaner. The compiler catches optimization opportunities you'd miss.

Next.js switching to Turbopack as the default signals this isn't experimental anymore. They're running production infrastructure on it. That's not a beta feature, that's the new baseline.

React Compiler does the same thing for runtime performance. You don't think about memoization. You write your components. The compiler optimizes them.

What To Do

  1. Update to React 19+ (or 17/18 with react-compiler-runtime)
  2. Install the compiler: npm install babel-plugin-react-compiler@latest
  3. Configure it (Next.js: experimental flag, Vite: Babel plugin)
  4. Remove React.memo from components where it's not needed
  5. Remove most useCallback/useMemo (keep for useEffect deps)
  6. Watch your bundle size and build times

The React Compiler installation guide has framework-specific setup for Next.js, Remix, Vite, and others. The Next.js 16 announcement covers Turbopack details.

The React ecosystem moves fast, but this feels different. Compiler 1.0 and Turbopack becoming default aren't about learning new patterns—they're about the tools getting better while you keep writing the same code.

That's the best kind of upgrade.