React Compiler in 2026: Automatic Memoization and Interview Questions
Master React Compiler interview questions for 2026. Covers automatic memoization, HIR compilation pipeline, Rules of React, ESLint integration, and when manual optimization still matters.

React Compiler reached stable v1.0 in October 2025, fundamentally changing how performance optimization works in React applications. For technical interviews in 2026, understanding the compiler's internals, its memoization strategy, and the scenarios where manual optimization still applies has become essential.
React Compiler is a build-time tool that automatically memoizes components and hooks through static analysis. It eliminates the need for manual useMemo, useCallback, and React.memo in most cases — but not all. Interviewers expect candidates to articulate both what the compiler handles and where it falls short.
What Is React Compiler and How Does It Optimize Code?
React Compiler is a build-time optimizing compiler that analyzes React components and hooks, then inserts granular memoization where beneficial. Unlike manual memoization with useMemo or useCallback, the compiler can memoize conditionally and at a finer granularity than any developer would reasonably maintain by hand.
The compiler operates as a Babel plugin (with SWC support growing in Next.js 15.3.1+). It processes each component independently, transforming the Babel AST into a custom High-Level Intermediate Representation (HIR) before running multiple optimization passes.
Production results from Meta confirm the impact: the Quest Store saw up to 12% faster initial loads and over 2.5x faster interactions. Sanity Studio reported 20-30% reduction in render time across 1,231 compiled components.
Interview answer structure: Define the compiler, explain it operates at build time (not runtime), mention the HIR pipeline, and cite real-world metrics.
The Compilation Pipeline: From Source to Optimized Output
This question tests deep understanding. The React Compiler pipeline has seven distinct phases:
- Source to AST — Babel parses JavaScript/TypeScript into an Abstract Syntax Tree
- AST to HIR — The compiler lowers the AST into its High-Level Intermediate Representation, designed specifically for React's component model
- SSA Transform — Single Static Assignment ensures each variable is assigned exactly once, enabling precise data-flow tracking
- Type Inference and Effect Analysis — The compiler classifies operations by their effects: read, store, capture, mutate, freeze
- Reactive Analysis — Every expression is classified as either static (constants, imports) or reactive (derived from props, state, context)
- Scope Discovery — The compiler identifies independent memoization scopes that can be cached and invalidated separately
- Code Generation — Optimized JavaScript with automatic memoization is emitted
// Before compilation
function UserProfile({ user, theme }) {
const fullName = user.firstName + ' ' + user.lastName;
const style = { color: theme.primary, fontSize: 16 };
return <div style={style}>{fullName}</div>;
}
// After compilation (simplified representation)
function UserProfile({ user, theme }) {
const $ = useMemoCache(4);
let fullName;
if ($[0] !== user.firstName || $[1] !== user.lastName) {
fullName = user.firstName + ' ' + user.lastName;
$[0] = user.firstName;
$[1] = user.lastName;
$[2] = fullName;
} else {
fullName = $[2];
}
// style and JSX similarly memoized...
}The key insight for interviews: the compiler memoizes at the value level, not the component level. Each computed value gets its own cache slot, invalidated only when its specific dependencies change. This granularity surpasses what useMemo achieves in practice.
Rules of React: What the Compiler Assumes
React Compiler performs static analysis under the assumption that components follow the Rules of React. When code violates these rules, the compiler skips optimization for that component — silently. This is a frequent interview topic.
The three core rules:
- Components and hooks must be pure — Given the same inputs, render must produce the same output. No reading or writing external mutable state during render.
- Hooks must follow calling conventions — Hooks cannot be called conditionally, inside loops, or in nested functions.
- Props and state are immutable within a render — Never mutate props or state directly; always use setter functions.
// Rule violation: mutating during render
function BadCounter({ items }) {
// The compiler will skip this component
items.sort(); // Mutates the prop array!
return <ul>{items.map(i => <li key={i}>{i}</li>)}</ul>;
}
// Correct: create a new sorted array
function GoodCounter({ items }) {
const sorted = [...items].sort();
return <ul>{sorted.map(i => <li key={i}>{i}</li>)}</ul>;
}When the compiler skips a component, it does not throw an error — the app still works, just without optimization. The ESLint plugin (eslint-plugin-react-hooks with the recommended preset) is the primary way to catch these violations before they reach production.
ESLint Integration: Catching Violations Before Build
The standalone eslint-plugin-react-compiler package is deprecated as of late 2025. All compiler-related lint rules now live in eslint-plugin-react-hooks@latest.
Setup with ESLint flat config:
import reactHooks from 'eslint-plugin-react-hooks';
import { defineConfig } from 'eslint/config';
export default defineConfig([
reactHooks.configs.flat.recommended,
]);The compiler-powered rules catch three critical patterns:
set-state-in-render— CallingsetStateduring render, causing infinite loopsset-state-in-effect— Expensive computations inside effects that trigger cascading re-rendersrefs— Accessing.currenton refs during render (refs are mutable escape hatches, not render-safe)
For interviews, the recommended adoption strategy: enable the ESLint rules first, fix all violations, then enable the compiler. This phased approach minimizes surprises.
When Manual Optimization Still Matters
The compiler does not eliminate all performance work. Several scenarios still require manual intervention:
1. External store subscriptions
The compiler only tracks React state, props, and context. External stores (Redux, Zustand, MobX) require useSyncExternalStore or the store's own selector mechanism for render optimization.
2. Expensive computations with large datasets
While the compiler memoizes return values, it does not profile execution cost. A function filtering 100,000 items still runs when its dependencies change. For truly expensive operations, useMemo with explicit dependencies remains valid — though the compiler will not duplicate the memoization.
3. Ref-based imperative logic
Refs are intentionally excluded from the compiler's reactive model. Animations, canvas drawing, and third-party DOM library integration still require manual control.
4. Cross-component memoization
The compiler memoizes within a single component or hook. Sharing computed values across components still requires lifting state, context, or external cache layers.
// The compiler handles this automatically
function ProductCard({ product, currency }) {
const formattedPrice = formatCurrency(product.price, currency);
const discount = product.originalPrice - product.price;
return (
<div>
<span>{formattedPrice}</span>
{discount > 0 && <Badge>Save {discount}</Badge>}
</div>
);
}
// Manual optimization still needed: expensive external computation
function DataGrid({ rows }) {
const processedRows = useMemo(
() => rows.map(row => heavyTransform(row)), // O(n) with large n
[rows]
);
return <VirtualList items={processedRows} />;
}Ready to ace your React / Next.js interviews?
Practice with our interactive simulators, flashcards, and technical tests.
How to Enable React Compiler in Different Frameworks
Interviewers often test practical knowledge of toolchain setup:
Next.js (15.3.1+): SWC-native support. Enable in next.config.js:
const nextConfig = {
experimental: {
reactCompiler: true,
},
};
export default nextConfig;Vite 8 with @vitejs/plugin-react v6: Since v6 dropped internal Babel for oxc, the compiler requires @rolldown/plugin-babel:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import babel from '@rolldown/plugin-babel';
import { reactCompilerPreset } from 'babel-plugin-react-compiler';
export default defineConfig({
plugins: [
react(),
babel({ presets: [reactCompilerPreset] }),
],
});Expo SDK 54+: Enabled by default. No configuration needed.
React Compiler v1.0 works with React 17, 18, and 19. However, the full optimization surface is available only with React 19, where the runtime supports fine-grained cache invalidation through useMemoCache.
React Compiler vs. Manual Memoization: Interview Comparison
| Aspect | React Compiler | Manual (useMemo/useCallback) |
|--------|---------------|----------------------------------|
| Granularity | Value-level, per expression | Block-level, developer-defined |
| Conditional memoization | Supported | Not possible |
| Maintenance cost | Zero — automatic | High — dependency arrays, wrapper components |
| Cross-component | Single component scope | Single component scope |
| External stores | Not tracked | Not tracked (use useSyncExternalStore) |
| Class components | Not supported | N/A (use React.memo) |
| Build requirement | Babel plugin or SWC | None |
| Performance ceiling | 20-60% fewer re-renders (typical) | Depends on developer skill |
The interview-ready summary: the compiler automates the 80-90% of memoization that developers previously handled manually, with better granularity and zero maintenance overhead. The remaining 10-20% involves external integrations, truly expensive computations, and imperative DOM work.
Common Interview Questions with Concise Answers
Q: Does React Compiler work at build time or runtime?
Build time. The compiler is a Babel plugin that transforms source code during compilation. The optimized output uses a runtime helper (useMemoCache) to store cached values, but all analysis happens before deployment.
Q: Should existing useMemo and useCallback calls be removed?
The React team recommends keeping existing manual memoization in place. Removing it can change compilation output in subtle ways. For new code, rely on the compiler and add manual memoization only after profiling identifies a specific need.
Q: What happens when the compiler encounters code it cannot optimize? It silently skips that component or hook. The application still functions correctly — that specific piece simply runs without automatic memoization. The ESLint rules surface these cases during development.
Q: How does the compiler interact with Server Components? Server Components run on the server and produce serialized output — they are not re-rendered on the client. The compiler targets client components where re-renders are the primary performance concern. The two optimizations are complementary: Server Components reduce bundle size, the compiler reduces client re-render cost.
Q: Can the compiler optimize custom hooks? Yes. The compiler analyzes both components and hooks. A custom hook that computes derived state will have its return values memoized automatically, benefiting every component that calls it.
Conclusion
- React Compiler v1.0 is a build-time tool that inserts granular, value-level memoization through a seven-phase compilation pipeline (AST, HIR, SSA, type inference, effect analysis, reactive analysis, code generation)
- The compiler assumes components follow the Rules of React; violations cause silent opt-out, caught by
eslint-plugin-react-hookswith therecommendedpreset - Manual optimization remains necessary for external store subscriptions, expensive computations with large datasets, ref-based imperative logic, and cross-component caching
- Practical setup varies by framework: SWC-native in Next.js,
@rolldown/plugin-babelin Vite 8, default-on in Expo SDK 54+ - For interviews, articulate both what the compiler automates (80-90% of memoization) and what it does not (external state, expensive cross-component computations, class components)
- The recommended adoption path is ESLint rules first, then compiler enablement — expect interviewers to ask about this phased strategy
Start practicing!
Test your knowledge with our interview simulators and technical tests.
Tags
Share
Related articles

Advanced React Hooks: Patterns and Optimizations
Master advanced React Hooks with proven patterns. Custom hooks, optimized useEffect, useMemo, useCallback and performance techniques.

React 19: Server Components in Production - The Complete Guide
Master React 19 Server Components in production. Architecture, patterns, streaming, caching, and optimizations for high-performance applications.

React Server Components in Production: Patterns and Pitfalls
React Server Components in production: battle-tested patterns, common anti-patterns, and debugging strategies for robust Next.js 15 applications.