React Compiler 1.0: Do You Still Need useMemo in 2026?
In short
No. For referential equality and re-render prevention, you no longer need useMemo in 2026: React Compiler 1.0 handles it at build time, and it has been stable since October 7, 2025. I enabled it on the dashboard of my production reputation SaaS and average commit duration dropped from 14.2ms to 9.1ms, with zero manual memoization left in the compiled files. What survives is a short list: genuinely expensive computations, values crossing non-React boundaries, and code in files the compiler skips. Here is where that line sits as of June 2026, with profiler numbers from a real app.

On this page
- What does React Compiler 1.0 actually do?
- Do you still need useMemo in 2026?
- What still breaks React Compiler, and why are teams stuck there?
- What did the profiler show before and after on a real dashboard?
- How do you migrate an existing app to React Compiler?
- Should a new project and an existing codebase make the same call?
- Key takeaways
What does React Compiler 1.0 actually do?
React Compiler is a build-time tool that rewrites your components and hooks to memoize values and skip re-renders automatically, giving you the effect of useMemo, useCallback, and React.memo without writing them. React Compiler 1.0 was released October 7, 2025 at React Conf in Henderson, Nevada, battle-tested at Meta, and works for both React and React Native.
That first sentence is the whole pitch, but the mechanics matter. The compiler analyzes your code against the Rules of React and inserts fine-grained memoization at the value level, not just the component level. It can skip re-rendering a subtree, and it can also avoid recomputing a single derived array inside a component that re-renders anyway. Hand-written React.memo wrappers cannot match that granularity without making the code unreadable.
As of June 2026, the tooling defaults have caught up. Expo, Vite, and Next.js enable the compiler for new apps, and the compiler-powered lint rules ship in the recommended presets of eslint-plugin-react-hooks. If you are upgrading a framework at the same time, do the framework first; I documented the order of operations in my Next.js 16 migration guide ↗ because compiler problems and framework breakages look identical in a stack trace. The React Native support is real too, and it nudges the cross-platform math from my React Native vs Flutter comparison for startup MVPs ↗ further toward React Native for teams already shipping React on the web.
Do you still need useMemo in 2026?
For referential equality, no. You no longer need useMemo; the compiler handles it. You still hand-memoize genuinely expensive computations and values crossing non-React boundaries, plus anything living in files the compiler skips. A useMemo wrapping an object literal or a filtered list of fifty rows is dead weight in a compiled file.
The three survivor categories, concretely:
- Genuinely expensive computations. Parsing a CSV export, sorting 10,000 review rows, building a client-side search index. The compiler memoizes these too, but I keep the explicit
useMemobecause it documents cost for the next reader and protects the work if the file later gets skipped. - Values crossing non-React boundaries. A comparator passed into a charting library, an options object handed to a map SDK, a message posted to a web worker. The compiler guarantees nothing about how foreign code treats identity, so I stay explicit there.
- Files the compiler skips. A skipped file gets zero automatic memoization, so the pre-2025 rules apply in full inside it.
// Still worth writing in 2026: the parse is the expensive part,
// and the useMemo documents that for the next reader.
const sortedReviews = useMemo(
() => parseReviewExport(csvText).sort(byDateDesc),
[csvText]
);
What still breaks React Compiler, and why are teams stuck there?
The breakage pattern is almost always the same: libraries break the compiler when they return a stable function identity that yields different values over time; memoizing on that identity means the value never updates. As of June 2026, this is the ecosystem's real adoption blocker, more than anything in the compiler itself.

Picture an older form library whose watch() function keeps the same identity forever while returning fresh values on every render. The compiler sees a stable input, caches the output, and your form silently stops updating. No error, no warning, just stale UI. That failure mode is what scared teams off through 2025.
Two things changed since. The compiler now ships detection that auto-skips files importing known incompatible libraries (landed in facebook/react PR #34027), and a matching incompatible-library lint rule tells you why a file was skipped instead of leaving you guessing. The 'use no memo' directive remains the per-file escape hatch for anything the detection misses.
The offenders I have personally hit or had flagged in client work:
| Library | Failure mode under compilation | Fix as of June 2026 |
| react-hook-form (older v7 builds) | Stale watch/formState, validation stops firing | Upgrade to the current release |
mobx-react observer | Components stop reacting to store changes | Upgrade to a compiler-aware release, or skip those files |
| react-beautiful-dnd | Drag state freezes mid-drag; library is unmaintained | Migrate to @hello-pangea/dnd or dnd-kit |
| react-table v7 (legacy) | Stale row models after data updates | Migrate to TanStack Table v8 |
| use-context-selector | Selectors return stale slices | Replace with plain context plus the compiler |
| Metric (60s scripted session) | Before compiler | After compiler |
| Commits | 41 | 23 |
| Average commit duration | 14.2ms | 9.1ms |
| Slowest commit | 48.6ms | 30.9ms |
| Components auto-memoized | 0% | 86% |
| Files skipped by compiler | n/a | 11 of 142 |
| Situation | My call | |
| New app (Next.js, Expo, Vite) | Compiler on day one, zero manual memoization | |
| Existing app, modern dependencies | Enable per directory, profile, delete redundant memos | |
| Existing app, flagged legacy libraries | Replace the libraries first, or ship 'use no memo' deliberately | |
| You publish a library | Test under compilation; stable-identity APIs need a redesign |
After eight months running it in production, my rule is simple: delete manual memoization in compiled files unless the profiler objects. The
useMemocalls that remain in our codebase are documentation of genuinely expensive work, not guesses about re-renders.
Key takeaways
- React Compiler 1.0 was released October 7, 2025 at React Conf, battle-tested at Meta, and works for both React and React Native.
- For referential equality and re-render prevention you no longer need
useMemo; keep it for genuinely expensive computations and non-React boundaries. - Libraries returning a stable function identity that yields different values over time are the main breakage; since PR #34027 the compiler auto-skips known offenders and lints the rest.
- My production numbers were real but modest: commits from 41 to 23, average commit from 14.2ms to 9.1ms, 86 percent of components auto-memoized.
- Migrate in five steps: lint, fix, enable per directory, profile, then delete redundant memoization.
FAQ
Should I remove useMemo and useCallback after enabling React Compiler?
Yes, in compiled files, once the profiler confirms the file is actually compiled. The compiler applies its own memoization, so manual calls become noise that hides the few that matter. Keep the ones guarding genuinely expensive computations and values crossing non-React boundaries; those still earn their place and now read as documentation.
Why is React Compiler skipping some of my components?
Three common reasons: the file violates the Rules of React and the compiler bails out, the file imports a library on the known-incompatible list and gets auto-skipped (behavior added in facebook/react PR #34027), or someone added `'use no memo'`. The incompatible-library lint rule and the hooks lint preset will tell you which case applies.
Does React Compiler work with React Native and Next.js 16?
Yes. The 1.0 release supports both React and React Native, and as of June 2026 Expo, Vite, and Next.js all enable the compiler for new apps. On Next.js 16 it runs inside the standard build pipeline; on bare React Native you wire it through the Babel config. My SaaS runs it in both web and mobile builds.
Working on something like this?
I build web apps, AI features, and mobile products for clients. If this article matches a problem you have, tell me about it.
Start a conversationMalik Hamza Shabbir · Full-Stack & AI Engineer
I build full-stack and AI products solo: a reputation SaaS in production, RAG pipelines, and React Native apps. I write from what I ship, not from documentation summaries.
Related articles
GEO in 2026: Getting Cited by ChatGPT and Perplexity
GEO means writing answer-first chunks AI engines can lift: 69% of Google searches are zero-click in 2026, but ChatGPT referrals convert at 15.9%.
Leaving Vercel in 2026: The Real Self-Hosting Cost Math
Self-hosting Next.js on Hetzner with Coolify costs me $6-17/mo vs $40-150 on Vercel Pro. The real math, ops hours included, after the April 2026 breach.
Next.js 16 Migration Guide: Fixing the Silent Breakages
Next.js 16 breaks middleware, revalidateTag, and caching with zero errors. Exact symptoms and fixes from migrating my production SaaS in 14 hours.