Now that the React Compiler hit v1.0 (October 2025) and is getting widespread adoption, I’m confused about whether I should still be writing useMemo, useCallback, and React.memo manually in my components.
Our team just upgraded to React 19 + the compiler, and our bundle went through the build pipeline without issues. But we have hundreds of existing useMemo calls scattered across the codebase.
Specifically:
Does the React Compiler handle all the cases that useMemo and useCallback used to cover?
Are there edge cases where manual memoization is still necessary?
Should we actively remove existing useMemo/useCallback calls, or just stop writing new ones?
Would love to hear from anyone who has migrated a production app.
This is seed content posted by the DevForums team to help get our community started. Have a better answer or want to add context? Jump in!
Great question — this is one of the most common things teams are working through right now after the React Compiler GA.
Short answer
The React Compiler automatically memoizes component output and the intermediate values/callbacks inside your components. For the vast majority of cases, you can stop writing useMemo, useCallback, and React.memo entirely.
What the compiler handles
The compiler analyses your component code at build time and inserts memoization where it detects value or reference changes would cause unnecessary re-renders. This covers:
Expensive derived computations (the classic useMemo case)
Callback references passed to child components (the classic useCallback case)
The compiler inserts the equivalent memoization automatically during compilation.
Edge cases where manual memoization may still matter
Code outside the compiler’s scope — if you have utility modules or non-component functions that create expensive objects consumed by components, the compiler won’t see those.
Third-party libraries with reference-sensitive APIs — some libraries (e.g., certain animation or charting libs) rely on stable references in ways the compiler may not fully track.
Custom hooks that escape analysis — very dynamic patterns using eval or heavy meta-programming can confuse the static analysis.
These are genuinely rare in most apps.
Migration strategy
My recommendation for your codebase with hundreds of existing calls:
Don’t do a bulk removal — leave existing ones in place. They’re harmless (the compiler respects them and won’t double-memoize).
Remove opportunistically during regular code changes to keep things tidy.
Run the compiler’s linter plugin (eslint-plugin-react-compiler) — it flags patterns the compiler can’t optimise and will tell you if any of your manual memos are actually still needed.
Hope that helps. The compiler is genuinely one of the biggest DX wins React has shipped — enjoy the cleaner code!