React Native's New Architecture in Production: 6 Months Later

By amillionmonkeys
#React Native#Mobile Development#Performance

We migrated our festival app to React Native's new architecture. Performance wins, migration pain points, and why we're not going back.

The Migration We Couldn't Ignore

Six months ago, we migrated our largest React Native app—a festival discovery app with 50,000+ users—to React Native's new architecture. The old architecture was showing its age: janky lists, slow native module calls, and that persistent feeling that we were fighting the framework rather than working with it.

The new architecture promised better performance through Fabric (the new rendering system) and TurboModules (synchronous native module access). We were skeptical. Framework rewrites usually mean "rewrite your app," but React Native's backwards compatibility meant we could migrate incrementally.

This is what actually happened over six months in production.

What Changed (And Why It Matters)

React Native's new architecture replaces two fundamental pieces:

Fabric replaces the legacy renderer: Instead of the old bridge sending serialized UI updates across threads, Fabric uses JSI (JavaScript Interface) for direct synchronous calls to native code. The theory: faster UI updates, smoother animations.

TurboModules replace native modules: The old bridge queued all native module calls asynchronously. TurboModules use JSI for synchronous access. The theory: no more waiting for native data.

Read more in the official React Native architecture docs.

Our Migration Timeline (The Real Story)

Month 1: Getting It Running

We followed the migration guide, but the first build took three days to debug. Our custom native modules broke immediately—we'd written five modules for camera access, offline storage, and analytics.

The fix: Convert each module to TurboModule specs. This wasn't automatic. We had to write Codegen specs for every module interface. For our analytics module alone: 120 lines of spec code.

Month 2: Third-Party Library Hell

Of our 43 dependencies, 8 didn't support the new architecture. React Native Camera was the biggest blocker—no TurboModule support yet. We switched to react-native-vision-camera, which meant rewriting our photo capture flows.

Two libraries (react-native-maps and react-native-blur) worked but threw warnings. We ignored them (probably not wise) and they've been fine in production.

Month 3: First Production Deploy

We shipped to 10% of users with feature flags. Initial crash rate: 0.8% (up from our baseline 0.3%). The crashes were all in our camera module—race conditions we'd never seen with the old bridge's async behaviour.

Fixed with proper thread-safety and mutex locks. Crash rate dropped to 0.25%.

Month 4-6: Performance Tuning

This is where it got interesting.

Performance Wins (With Real Numbers)

We measured everything with our analytics setup and production monitoring.

List Performance: 40% Faster Scrolling

Our festival lineup screen renders 200+ artists. With the old architecture:

  • Time to render: 1,840ms average
  • Janky frames (>16ms): 28% of scrolls
  • User complaints: weekly

With Fabric:

  • Time to render: 1,100ms average
  • Janky frames: 11% of scrolls
  • User complaints: down 70%

The difference is visible. Scrolling feels like a native iOS app now, not "React Native scrolling."

Native Module Calls: 3x Faster

We call our storage module hundreds of times per session. Old bridge average: 12ms per call. TurboModules average: 4ms.

This compounds. On app launch, we make 40 storage calls. That's 480ms saved on every app open. Users noticed—our "time to interactive" metric improved by 35%.

Memory Usage: Actually Worse (Then Better)

Initial Fabric deploy increased memory by 18MB average. This was unexpected. Turned out we were holding onto references in our JSI layer. After auditing our native modules and fixing leaks, we ended up 8MB better than the old architecture.

Lesson: JSI makes it easier to leak memory if you're not careful with native object lifecycles.

Bundle Size: Slightly Larger

App size increased 2.1MB (from 38.4MB to 40.5MB). Acceptable trade-off for the performance gains. Most of the increase is Fabric's C++ code.

What Broke (The Pain Points)

1. Hermes Required

The new architecture strongly encourages Hermes (React Native's JavaScript engine). We were on JSC (JavaScriptCore). Switching to Hermes broke our Redux DevTools setup and required rewriting some Date handling (Hermes has stricter ECMA compliance).

Worth it—Hermes startup time is 30% faster—but be ready for compatibility issues.

2. Debugging Is Harder

Chrome DevTools doesn't work with Fabric. We use Flipper now, which is fine but has a learning curve. The crash stack traces are also less readable when errors cross the JSI boundary.

3. iOS Build Times Doubled

Our iOS build went from 4 minutes to 8 minutes in CI. The new architecture compiles a lot more C++ code. We upgraded our CI machines and implemented better caching, which brought it down to 6 minutes.

4. Android ProGuard Nightmares

ProGuard was aggressive with the new C++ dependencies. Release builds crashed on launch for two days until we figured out the right keep rules. Here's what worked:

-keep class com.facebook.react.** { *; }
-keep class com.facebook.jni.** { *; }
-keep class com.facebook.hermes.** { *; }

Your mileage will vary based on your dependencies.

Why We're Not Going Back

Despite the migration pain, we're committed to the new architecture:

1. Performance Is Measurably Better

Our users feel it. App Store reviews mentioning "smooth" or "fast" increased 3x after the migration. That's the kind of win that justifies the effort.

2. The Old Architecture Is Dead

React Native's team is clear: future optimization and features target the new architecture. Staying on the old bridge means falling behind. We'd rather deal with migration now than in two years when it's forced.

3. Better Developer Experience (Eventually)

After the initial pain, developing with TurboModules is nicer. Synchronous native calls mean simpler code—no more async ceremonies for every native interaction. Our codebase has 30% fewer callbacks since the migration.

4. Native Modules Are Easier to Write

Codegen is verbose but reduces boilerplate. Once you write the spec, Codegen generates the native bindings. We've added two new native modules since migrating, and both took half the time of our old bridge modules.

Should You Migrate?

Migrate if:

  • You're building a new app (enable new architecture from day one)
  • You have performance problems the old architecture can't solve
  • You have time for 2-3 months of migration and testing
  • Your dependencies support the new architecture

Wait if:

  • You rely on libraries without TurboModule support
  • You don't have capacity for a major technical migration
  • Your app performs fine and you're not adding features

Check your dependencies against React Native Directory's new architecture filter before committing.

Key Takeaways

After six months in production:

  • 40% faster list rendering in our most critical screens
  • 3x faster native module calls improving startup time
  • Migration took 3 months end-to-end (1 month part-time planning, 2 months full-time implementation)
  • Worth it for performance, painful for debugging and build times
  • Not going back—the old architecture is a dead end

The new architecture isn't perfect. Debugging is harder, builds are slower, and the migration has sharp edges. But the performance wins are real, and React Native's future is clearly here.

If you're planning a similar migration, budget more time than you think for dependency updates and expect to rewrite some native code. The framework-level improvements are excellent, but they don't come free.


Considering React Native for your next mobile app? We've migrated multiple production apps to the new architecture and can help you avoid the gotchas. Get in touch about your project.

For more on our mobile development process, check out our mobile app development services or read about our work on the Latitude Festival app.

T: 07512 944360 | E: [email protected]

© 2025 amillionmonkeys ltd. All rights reserved.