Beyond the Memo: Engineering High-Performance Universal Apps with the React Compiler and Expo
Stop chasing re-renders manually. Learn how I integrated the new React Compiler into a cross-platform Expo workflow to achieve near-native performance without the useMemo boilerplate.

Beyond the Memo: Engineering High-Performance Universal Apps
I’ve spent a significant portion of my career as a software engineer chasing the ghost of the unnecessary re-render. We’ve all been there: wrapping every function in useCallback, squinting at dependency arrays in useMemo, and hoping we didn't just create a memory leak or a stale closure. It’s manual labor that distracts from what we actually want to build.
Recently, I've been diving deep into the React Compiler (formerly known as React Forget) within the context of Expo. If you’re building universal apps—targeting iOS, Android, and Web from a single codebase—this isn't just an incremental update. It’s a fundamental shift in how we think about high-performance architecture.
The Memoization Tax
In a standard React Native or Web app, memoization is an opt-in strategy. We wait for a performance bottleneck, fire up the profiler, and start slapping React.memo on components. This is what I call the "Memoization Tax." It costs developer time, increases code complexity, and is incredibly fragile.
In my experience, manual memoization fails in two ways:
- Under-memoization: The app feels sluggish on low-end Android devices because a parent state change triggers a massive subtree re-render.
- Over-memoization: Developers wrap everything, leading to bloated code and hard-to-track bugs where UI doesn't update because a dependency was missed.
Enter the React Compiler
The React Compiler changes the game by moving memoization from a runtime responsibility to a build-time transformation. It analyzes your JavaScript/TypeScript code and automatically inserts the equivalent of memoization where it’s needed, following the "Rules of React."
Why Expo is the Ideal Sandbox
Integrating the compiler into a vanilla React Native project can be a headache. However, with Expo SDK 51 and 52, the integration is remarkably smooth. Because Expo manages the Metro bundler configuration and the Babel/SWC pipeline, we can toggle the compiler on and see immediate results across all platforms.
Technical Implementation: Setting it Up
To get started in an Expo environment, you first need to install the compiler plugin. In my current workflow, I use the Babel version as it's the most stable for the Metro pipeline:
Then, update your babel.config.js:
Note: Ensure you are running React 18.3 or 19-RC to have the necessary runtime globals for the compiler's output.
Real-World Breakthroughs
I recently refactored a complex dashboard feature that rendered real-time financial data. The component tree was deep, involving multiple charts (SVG via react-native-svg) and filtered lists.
The "Before" State
I had a PriceRow component that looked like this to stay performant:
The "After" State with the Compiler
With the React Compiler, I deleted the boilerplate. The code became cleaner, more readable, and—crucially—faster because the compiler is more granular than a human could ever be.
In my testing on a budget Android device (Moto G series), the interaction latency dropped by nearly 30% because the compiler optimized the entire render pass, not just the leaf nodes.
The Engineering Constraints
It’s not magic; it’s engineering. The compiler is strict. If you’ve been playing fast and loose with the Rules of React (e.g., mutating props or calling hooks conditionally), the compiler will simply skip those components.
I recommend using the React Compiler ESLint plugin. It catches these issues before you even try to build:
Universal Performance: Web vs. Native
One of the biggest wins I've found is on the Web target. When using Expo Router to build SEO-friendly sites, the React Compiler drastically reduces the amount of work the main thread does during hydration. For mobile, it reduces the bridge traffic (or JSI overhead in the New Architecture) because fewer redundant updates are being sent to the native layer.
Final Thoughts
We are entering an era where performance is an implementation detail of the language/compiler rather than a manual optimization task. For senior engineers, this means we can stop code-reviewing dependency arrays and start focusing on high-level architecture, state management patterns, and user experience.
If you're running Expo, try turning it on for one feature folder first using the sources config in the plugin. The speed might surprise you.
Keep building.