Skip to content
Malik Hamza Shabbir
Web Developmentreactreact-compilerperformanceusememo

React Compiler 1.0: Do You Still Need useMemo in 2026?

HSMalik Hamza Shabbir6 min read

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.

React Compiler 1.0: Do You Still Need useMemo in 2026? - branded cover card by Hamza Shabbir
On this page

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 useMemo because 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.


TSX
// 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.

React DevTools profiler showing fewer commits and shorter render durations after enabling React Compiler 1.0 on a production dashboard
React DevTools profiler showing fewer commits and shorter render durations after enabling React Compiler 1.0 on a production dashboard

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:







What did the profiler show before and after on a real dashboard?

On my reputation SaaS dashboard, roughly 120 components across review lists, filters, and an AI reply panel, the React DevTools profiler showed commits dropping from 41 to 23 over a scripted 60-second session, and average commit duration falling from 14.2ms to 9.1ms. Useful and real, but not a miracle.







Methodology, so you can repeat it: same production build flags, the same seeded data set of 1,200 reviews, one scripted minute of typing in search, toggling filters, and opening three reply drawers, profiled with React DevTools at 4x CPU throttling. Of the 11 skipped files, 7 were auto-skipped by the incompatible-library detection (our pinned react-beautiful-dnd widget grid), 2 carry a deliberate 'use no memo', and 2 have rule violations I have not fixed yet.

The honest read: on my laptop the dashboard felt identical. On the throttled profile, and on the three-year-old Android tablet one client actually uses at their front desk, search-as-you-type stopped dropping frames. That gap between the benchmark and the felt experience is most of what I look for in app rescue and optimization work : the wins show up on the hardware your worst-case user owns.

How do you migrate an existing app to React Compiler?

Five steps, in order: upgrade the lint preset, fix violations, enable the compiler per directory, profile before and after, then delete the redundant memoization. My dashboard took two evenings, and lint fixes were 80 percent of the effort. It is the same incremental playbook I used for the TypeScript 7 tsgo monorepo migration : one directory at a time, with a revert path.

  1. Upgrade eslint-plugin-react-hooks to the recommended-latest preset. The compiler-powered rules flag exactly the code the compiler will refuse, before you enable anything.

  2. Fix the violations. In my case, mostly mutations during render and conditional hook patterns. Do not suppress them; suppressed files get silently skipped later.

  3. Enable the compiler per directory. Start with leaf feature folders, not your design system.

  4. Profile one real user flow before and after. Keep the script identical between runs.

  5. Delete redundant useMemo/useCallback and let remaining ones document genuinely expensive work.


TS
// vite.config.ts: enable per directory while migrating
react({
  babel: {
    plugins: [['babel-plugin-react-compiler', {
      sources: (filename) => filename.includes('src/features/reviews'),
    }]],
  },
})

Should a new project and an existing codebase make the same call?

No. On a new project, turn the compiler on from day one and write zero manual memoization; that is now my default on every client build I take on through my web development services . On an existing codebase, the compiler is a refactoring forcing function, and you should treat it like one.






LibraryFailure mode under compilationFix as of June 2026
react-hook-form (older v7 builds)Stale watch/formState, validation stops firingUpgrade to the current release
mobx-react observerComponents stop reacting to store changesUpgrade to a compiler-aware release, or skip those files
react-beautiful-dndDrag state freezes mid-drag; library is unmaintainedMigrate to @hello-pangea/dnd or dnd-kit
react-table v7 (legacy)Stale row models after data updatesMigrate to TanStack Table v8
use-context-selectorSelectors return stale slicesReplace with plain context plus the compiler
Metric (60s scripted session)Before compilerAfter compiler
Commits4123
Average commit duration14.2ms9.1ms
Slowest commit48.6ms30.9ms
Components auto-memoized0%86%
Files skipped by compilern/a11 of 142
SituationMy call
New app (Next.js, Expo, Vite)Compiler on day one, zero manual memoization
Existing app, modern dependenciesEnable per directory, profile, delete redundant memos
Existing app, flagged legacy librariesReplace the libraries first, or ship 'use no memo' deliberately
You publish a libraryTest 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 useMemo calls 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 conversation
HS

Malik 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