Back to blog

React Compiler: The End of Manual useMemo and useCallback in 2026

Hello HaWkers, after years of development, React Compiler v1.0 was released in October 2025 and adoption in 2026 is accelerating. The most significant change? Manual memoization hooks like useMemo, useCallback, and React.memo are becoming unnecessary in most cases. The compiler now does this automatically.

What does this mean for your existing code? And when does manual memoization still make sense?

What Changed

The evolution of React.

From Manual to Automatic

The optimization history:

Pre-Compiler Era (2019-2024):

  • useMemo for expensive calculations
  • useCallback for functions in props
  • React.memo for components
  • Lots of unnecessary memoization
  • Performance issues from missing memoization

Compiler Era (2025+):

  • Compiler analyzes the code
  • Adds memoization automatically
  • Removes hook overhead
  • Performance optimized by default
  • Less boilerplate code

How the Compiler Works

Build-time transformation:

// Your code (without manual optimization)
function ProductCard({ product, onAddToCart }) {
  const formattedPrice = formatCurrency(product.price);
  const discount = calculateDiscount(product);

  return (
    <div className="product-card">
      <h3>{product.name}</h3>
      <p>{formattedPrice}</p>
      {discount > 0 && <span>{discount}% OFF</span>}
      <button onClick={() => onAddToCart(product)}>
        Add to Cart
      </button>
    </div>
  );
}

// What the Compiler generates (simplified)
function ProductCard({ product, onAddToCart }) {
  const $ = useMemoCache(6);

  let formattedPrice;
  if ($[0] !== product.price) {
    formattedPrice = formatCurrency(product.price);
    $[0] = product.price;
    $[1] = formattedPrice;
  } else {
    formattedPrice = $[1];
  }

  // ... rest of component with cache
}

Before vs After

Comparing code.

Old Code (Pre-Compiler)

How we used to write:

// Before: Lots of optimization boilerplate
import { useMemo, useCallback, memo } from 'react';

const ProductList = memo(function ProductList({
  products,
  onSelect,
  category
}) {
  // Memoizing filter
  const filteredProducts = useMemo(() => {
    return products.filter(p => p.category === category);
  }, [products, category]);

  // Memoizing calculations
  const stats = useMemo(() => {
    const total = filteredProducts.length;
    const avgPrice = filteredProducts.reduce(
      (sum, p) => sum + p.price, 0
    ) / total;
    return { total, avgPrice };
  }, [filteredProducts]);

  // Memoizing callbacks
  const handleSelect = useCallback((product) => {
    onSelect(product);
  }, [onSelect]);

  return (
    <div>
      <Stats data={stats} />
      {filteredProducts.map(product => (
        <ProductCard
          key={product.id}
          product={product}
          onSelect={handleSelect}
        />
      ))}
    </div>
  );
});

New Code (With Compiler)

How we write now:

// Now: Clean code, compiler optimizes
function ProductList({ products, onSelect, category }) {
  const filteredProducts = products.filter(
    p => p.category === category
  );

  const total = filteredProducts.length;
  const avgPrice = filteredProducts.reduce(
    (sum, p) => sum + p.price, 0
  ) / total;

  return (
    <div>
      <Stats total={total} avgPrice={avgPrice} />
      {filteredProducts.map(product => (
        <ProductCard
          key={product.id}
          product={product}
          onSelect={() => onSelect(product)}
        />
      ))}
    </div>
  );
}

// No memo(), useMemo(), useCallback()
// Compiler handles everything

Setting Up the Compiler

Step by step setup.

Installation

Adding to project:

# Installing the compiler
npm install -D babel-plugin-react-compiler

# For ESLint (recommended)
npm install -D eslint-plugin-react-compiler

Babel Configuration

Adjustments in babel.config.js:

// babel.config.js
module.exports = {
  plugins: [
    ['babel-plugin-react-compiler', {
      runtimeModule: 'react/compiler-runtime',
    }],
  ],
  presets: [
    '@babel/preset-react',
    '@babel/preset-typescript',
  ],
};

Next.js Configuration

For Next.js projects:

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

module.exports = nextConfig;

When to Still Use Manual Hooks

Specific cases.

Controlled Side Effects

When useMemo still makes sense:

// STILL NECESSARY: Side effects in memo
function DataFetcher({ query }) {
  // useMemo to control when fetch happens
  const data = useMemo(() => {
    // This has side effect (logging, analytics)
    console.log('Fetching:', query);
    analytics.track('search', { query });

    return fetchData(query);
  }, [query]);

  // Compiler does NOT add side effects
  // Must be explicit here
}

External Library Integration

APIs expecting stable reference:

// STILL NECESSARY: External libraries
function MapComponent({ markers }) {
  const mapRef = useRef(null);

  // Some libs need stable reference
  const markerInstances = useMemo(() => {
    return markers.map(m => new google.maps.Marker(m));
  }, [markers]);

  const onMapClick = useCallback((event) => {
    if (mapRef.current) {
      mapRef.current.panTo(event.latLng);
    }
  }, []);

  return <GoogleMap ref={mapRef} onClick={onMapClick} />;
}

Performance Impact

Real results.

Benchmarks

Production numbers:

E-commerce Application (500 components):

Metric Manual Compiler Difference
Bundle size 245KB 238KB -3%
First render 180ms 165ms -8%
Re-render 45ms 38ms -16%
Memory 42MB 39MB -7%

Dashboard (200 widgets):

Metric Manual Compiler Difference
Time to Interactive 2.8s 2.4s -14%
Interaction latency 120ms 95ms -21%
CPU usage 45% 38% -16%

2026 Best Practices

How to write modern React.

Idiomatic Code

The new standard:

// RECOMMENDED: Simple and direct code
function UserProfile({ user, onFollow }) {
  // Inline calculations - compiler optimizes
  const fullName = `${user.firstName} ${user.lastName}`;
  const joinDate = formatDate(user.createdAt);
  const isVerified = user.followers > 10000;

  // Inline event handlers - compiler optimizes
  return (
    <div className="profile">
      <Avatar src={user.avatar} />
      <h2>{fullName}</h2>
      <span>{joinDate}</span>
      {isVerified && <VerifiedBadge />}
      <button onClick={() => onFollow(user.id)}>
        Follow
      </button>
    </div>
  );
}

// NOT RECOMMENDED: Over-engineering
function UserProfile({ user, onFollow }) {
  const fullName = useMemo(
    () => `${user.firstName} ${user.lastName}`,
    [user.firstName, user.lastName]
  ); // Unnecessary!

  const handleFollow = useCallback(
    () => onFollow(user.id),
    [onFollow, user.id]
  ); // Unnecessary!

  // ...
}

The React Compiler represents a paradigm shift in how we write React. In 2026, the standard is to write simple code and let the compiler optimize. Manual memoization hooks are becoming the exception, not the rule.

If you want to learn more about other React news, I recommend checking out another article: React 19.2 and Partial Pre-rendering: The New Era of Web Rendering where you will discover Partial Pre-rendering.

Let's go! 🦅

💻 Master JavaScript for Real

The knowledge you gained in this article is just the beginning. There are techniques, patterns, and practices that transform beginner developers into sought-after professionals.

Invest in Your Future

I have prepared complete material for you to master JavaScript:

Payment options:

  • 1x of $4.90 no interest
  • or $4.90 at sight

📖 View Complete Content

Comments (0)

This article has no comments yet 😢. Be the first! 🚀🦅

Add comments