React Compiler Explained: Do We Still Need useMemo and useCallback?
React Compiler is an official build-time optimization tool that automatically memoizes React components, values, and functions. Learn how it works, whether useMemo and useCallback are still necessary, how to configure it with Vite and Next.
One of the recurring challenges in React development is managing unnecessary re-renders and avoiding expensive calculations during component updates.
For years, developers have relied on tools such as useMemo, useCallback, and React.memo to control rendering behavior and improve performance.
Although these tools are useful, manual memoization introduces additional complexity. Developers must understand dependency arrays, preserve stable references, and decide which components or calculations actually need optimization.
React Compiler introduces a different approach: instead of requiring developers to manually identify every optimization opportunity, it analyzes React code at build time and automatically applies memoization where it can.
React Compiler reached its stable 1.0 release in October 2025. It is now suitable for production adoption, provided that applications follow React's rules and are properly tested.
In this article, we'll explore what React Compiler is, how automatic memoization works, whether traditional memoization Hooks are still necessary, and how to enable it in modern React applications.
React Compiler is a build-time optimization tool that analyzes React components and Hooks and automatically applies memoization to code that can be safely optimized.
In simple terms, it attempts to avoid unnecessary recalculations and re-renders without requiring developers to manually wrap every component, function, or computed value in memoization APIs.
Front-End Developer with 3+ years of experience building modern, responsive websites and web applications, focused on React, Next.js, performance, and user experience.
The Compiler analyzes this code and can generate the appropriate memoization logic during the build process.
The goal is not to change how developers think about React components. It is to reduce the amount of manual performance-related code they need to maintain.
Before understanding React Compiler, it helps to understand memoization.
Memoization is an optimization technique that caches the result of a calculation or preserves a reference so that unchanged inputs do not require unnecessary recomputation.
React Compiler performs this optimization at build time.
At a high level, the compiler analyzes your source code, builds an internal representation, tracks data flow and mutability, and generates memoization logic for expressions and components that can be optimized.
This can include:
Skipping unnecessary cascading re-renders.
Caching expensive calculations.
Preserving function and value references when appropriate.
Analyzing actual dependencies in a component.
Optimizing individual expressions rather than treating an entire component as one unit.
One important difference from manual memoization is that the compiler can optimize smaller sections of a function, including conditional sections, with more precise dependency analysis.
There are situations where manual memoization remains valuable:
When you need precise control over a cached value or function.
When reference stability matters for an Effect dependency.
When your application does not have React Compiler enabled.
When maintaining an existing codebase where removing memoization could change compilation output or runtime behavior.
The official React guidance is straightforward: for new code, rely on the compiler by default and use useMemo or useCallback when you need more precise control.
For existing codebases, do not remove all existing memoization blindly. Test the behavior and performance before making changes.
For newer versions of @vitejs/plugin-react, the official React documentation provides a setup using reactCompilerPreset and @rolldown/plugin-babel.
First, install the additional package:
npm install -D @rolldown/plugin-babel
Then configure vite.config.ts:
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()],
}),
],
});
This setup targets newer versions of the Vite React plugin. Older versions may use a different Babel configuration, so check your installed package versions before applying the configuration.
React Compiler support is stable in Next.js 16 and no longer requires an experimental configuration flag.
Install the compiler:
npm install -D babel-plugin-react-compiler
Then enable it in next.config.ts:
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
reactCompiler: true,
};
export default nextConfig;
That's it. Next.js will enable React Compiler as part of its build pipeline.
Earlier Next.js versions have different support and configuration details. The official documentation also describes support starting with Next.js 15.3.1.
If a component is too large, state is placed at the wrong level, or unnecessary data flows through the component tree, the compiler cannot automatically fix every architectural problem.
The compiler relies on React's programming model to analyze components safely.
Patterns such as mutating props or state, incorrectly using Hooks, or performing side effects during rendering can prevent parts of your code from being optimized.
No. The actual improvement depends on the application's architecture, rendering patterns, expensive calculations, and existing optimization strategies.
If an application is already well optimized, you may not notice a significant difference.
On the other hand, applications with excessive manual memoization or unnecessary cascading re-renders may benefit considerably.
The only reliable way to evaluate the impact is to measure performance before and after enabling the compiler under comparable conditions.
React Compiler represents an important step forward in the React developer experience.
By automating much of the memoization process, it allows developers to write simpler and more maintainable code without manually optimizing every component and function.
However, it does not replace a solid understanding of React, good component architecture, proper state management, or performance profiling.
My recommendations:
Consider enabling React Compiler in new React 19 applications.
Use incremental adoption when introducing it into existing projects.
Do not remove existing memoization without testing.
Measure real-world results with profiling tools.
Focus on application architecture rather than simply reducing the number of memoization Hooks.
Ultimately, the goal is not to eliminate every useMemo and useCallback call. The goal is to build faster applications with less unnecessary complexity.