DEV Community

Cover image for Optimizing React Native Apps With JSI & TurboModules
Sherry Walker
Sherry Walker

Posted on

Optimizing React Native Apps With JSI & TurboModules

React Native apps in 2025 run up to 40% faster at startup and maintain solid 60fps frame rates thanks to the New Architecture. The JavaScript bridge that once created bottlenecks is gone.

JSI and TurboModules eliminate JSON serialization overhead by enabling direct, synchronous communication between JavaScript and native code. For teams offering mobile app development utah services, understanding these technologies means building apps that feel truly native.

This guide explains how JSI and TurboModules work, their performance benefits, and practical implementation steps for production apps.

Understanding JSI and the Architectural Shift

The old React Native architecture relied on an asynchronous bridge between JavaScript and native code. Every method call required JSON serialization, which added latency and memory overhead.

JSI removes this bridge entirely. It provides direct C++ bindings that let JavaScript hold references to native objects and invoke methods synchronously.

How JSI Eliminates the Bridge

JSI creates a lightweight interface between JavaScript and native code using C++. This allows data to flow directly through memory references without serialization costs.

Native modules expose C++ objects that JavaScript can access instantly. Frame buffers around 30 MB in size can now transfer at nearly 2 GB per second, making real-time camera processing and heavy data operations possible.

Key JSI Benefits

  • Synchronous method calls reduce latency to near-zero
  • Memory references replace JSON serialization
  • Complex types like databases and images transfer efficiently
  • Thread-safe communication between JavaScript and native layers

Apps using JSI report 25% reduction in startup time and 30% improvement in memory usage compared to bridge-based architecture.

TurboModules: Next-Generation Native Modules

TurboModules replace the legacy NativeModules system with JSI-powered, type-safe alternatives. They load lazily and communicate directly with JavaScript.

The old architecture initialized all native modules at startup, wasting memory on unused functionality. TurboModules initialize only when your code calls them.

Lazy Loading and Performance Gains

TurboModules stay dormant until first use. This cuts startup time by 500ms on Android tablets and even more on lower-end devices.

Access happens through TurboModuleRegistry instead of NativeModules. The registry provides typed interfaces generated by Codegen, catching errors at compile time rather than runtime.

TurboModule Architecture

  • Type-safe bindings generated automatically from TypeScript specs
  • Direct JSI-based communication without bridge overhead
  • On-demand initialization reduces memory footprint
  • Synchronous and asynchronous methods both supported

Production benchmarks show TurboModules deliver 20% faster method invocation compared to bridge-based modules.

Codegen and Type Safety

Codegen reads TypeScript or Flow specifications and generates native code for Android and iOS. This eliminates manual bridge glue and prevents type mismatches.

You define your module interface once in TypeScript. Codegen produces Java, Kotlin, Objective-C, and C++ implementations automatically.

Implementing TurboModules in Your App

Enabling TurboModules requires React Native 0.80 or newer. The New Architecture ships as default in recent versions.

Enable New Architecture

Set the flags in your project configuration files.

Android: Edit android/gradle.properties and add newArchEnabled=true.

iOS: In your Podfile, enable with use_react_native!(:new_architecture_enabled => true).

Verify Hermes Engine

Hermes is the default JavaScript engine in modern React Native. It pairs with JSI to deliver faster startup and lower memory use.

Check your configuration files to confirm Hermes is enabled. Most projects created in 2024-2025 have it by default.

Create a TurboModule Specification

Define your module interface in TypeScript. Codegen looks for files matching the pattern Native{MODULE_NAME}.ts.

Example spec for a device info module:

export interface Spec extends TurboModule { getModel(): Promise<string>; isEmulator(): Promise<boolean>; }

Register the spec with TurboModuleRegistry.getEnforcing<Spec>('DeviceInfo') in your JavaScript code.

Configure Codegen

Add Codegen configuration to your package.json:

"codegenConfig": { "name": "AppModule", "type": "modules", "jsSrcsDir": "./src/native", "android": { "javaPackageName": "com.example.appmodule" } }

Run your build process. Codegen generates native stub files automatically during compilation.

Implement Native Code

Write your platform-specific implementations in Kotlin for Android and Swift or Objective-C for iOS. The generated interfaces guide what methods to implement.

Android implementations extend the generated abstract class. iOS implementations conform to the generated protocol.

Your native code can now communicate directly with JavaScript through JSI without any manual bridge setup.

Fabric Renderer and UI Performance

Fabric is the new rendering system that works alongside TurboModules. It uses JSI for synchronous UI updates and concurrent rendering capabilities from React 18.

The old renderer batched updates asynchronously through the bridge. Fabric allows immediate, prioritized updates that keep animations smooth even under load.

How Fabric Improves Rendering

Fabric unifies rendering logic across platforms using shared C++ code. Layout calculations happen faster and more consistently.

UI benchmarks show 60fps frame rates maintained during heavy list scrolling where the old architecture dropped to 45fps. Interaction latency drops noticeably on mid-range Android devices.

Concurrent Features

  • Automatic batching groups state updates to reduce re-renders
  • Suspense enables better loading state management
  • Transitions let you prioritize user interactions over background updates
  • Smoother animations through prioritized rendering paths

React Native 0.76 and newer enable Fabric by default. Legacy apps need migration but the performance gains justify the effort.

Performance Benchmarks and Real-World Impact

Meta's internal testing showed 500ms faster startup on TV emulators and 900ms improvement on Fire HD tablets when switching to the New Architecture.

Community benchmarks comparing Flutter, React Native, and native development in 2025 found React Native with JSI delivers near-native performance for database operations and UI rendering.

Startup Time Improvements

Apps using TurboModules and Hermes cut cold start time by 25-40%. Lazy module loading means only essential code initializes at launch.

The impact scales with app complexity. Large enterprise apps with dozens of native modules see the biggest gains.

Memory Efficiency

Memory usage drops 20-30% because unused modules never load and JSI eliminates bridge object duplication.

SQLite operations through JSI show sub-10ms response times for targeted queries, matching native Android and iOS performance.

Frame Rate and Responsiveness

Fabric maintains consistent 60fps during complex list rendering and gesture tracking. Frame drops that plagued the old architecture disappear.

Input latency improves measurably. Users perceive apps as more responsive because UI updates happen synchronously instead of waiting for bridge communication.

Migration Strategy for Existing Apps

Moving from the legacy architecture to JSI and TurboModules requires planning. Large codebases need phased rollouts to minimize risk.

Audit Dependencies

Check all third-party libraries for New Architecture support. Run npm outdated to find packages that need updates.

Popular libraries like React Navigation, React Native Paper, and major UI kits all support the New Architecture as of 2025. Smaller packages may need replacements or custom bridges.

Create a Migration Plan

  • Start with a dedicated feature branch for architecture changes
  • Enable New Architecture flags in development first
  • Convert one native module to TurboModule as proof of concept
  • Test thoroughly on physical devices before production rollout

Convert Native Modules

Pick a simple native module for your first conversion. Write the TypeScript spec, configure Codegen, and implement the native code.

Test the converted module extensively. Once stable, convert more complex modules one at a time.

Keep legacy bridge modules working alongside TurboModules during transition. TurboModuleRegistry falls back to bridge modules if the TurboModule version isn't available.

Performance Testing

Add performance markers to track startup time, frame rates, and interaction latency before and after migration.

Use React DevTools Profiler, Flipper, and platform-specific tools like Android Profiler and Xcode Instruments to measure improvements.

Feature Flags and Gradual Rollout

Deploy the New Architecture to a small percentage of users first. Monitor crash rates and performance metrics closely.

Expand gradually as confidence builds. Most production apps can fully migrate within 2-3 development cycles.

Common Implementation Challenges

Developers encounter predictable issues when implementing TurboModules. Understanding these helps avoid frustration.

Module Registration Errors

The most common problem is module name mismatches between JavaScript and native code. TurboModuleRegistry.get('ModuleName') must use the exact name registered in native code.

Case sensitivity matters. DeviceInfo and deviceInfo are different modules.

Type Mismatches

Codegen enforces strict type matching. If your TypeScript spec declares Promise<string> but native code returns something else, runtime errors occur.

Always run clean builds after spec changes. Stale generated code causes confusing errors.

iOS-Specific Considerations

iOS requires Objective-C++ files (.mm extension) not plain Objective-C (.m). Using the wrong file type prevents compilation.

iOS also has limitations with synchronous return types. Use Promise for cross-platform compatibility even if Android supports direct returns.

Debugging Tools

  • Flipper inspects module bridges and network requests
  • Xcode Console captures iOS native errors
  • Android Logcat shows detailed crash information
  • React DevTools profiles JavaScript performance

Break complex modules into smaller pieces during development. Test native methods independently before connecting to JavaScript.

Advanced Patterns and Optimizations

Once basic TurboModules work, advanced patterns unlock more performance and capabilities.

Shared C++ Implementations

Write native logic once in C++ and use it on both iOS and Android. This reduces code duplication and ensures consistency.

JSI makes C++ a first-class option for cross-platform native code. You get native performance without maintaining separate implementations.

Direct Memory Sharing

JSI enables passing large data structures by reference instead of copying. This matters for image processing, video frames, and large datasets.

Camera libraries like VisionCamera use this to process frames in real-time without killing performance.

Event Emitters and Streams

TurboModules support native-to-JavaScript events. Use NativeEventEmitter to send continuous updates like sensor data or location changes.

Events work differently from method calls. They're fire-and-forget, making them perfect for high-frequency updates that don't need responses.

Background Processing

Heavy operations should run on background threads. JSI handles thread management automatically in many cases.

Return promises for async work. This keeps the JavaScript thread responsive while native code processes data.

Frequently Asked Questions

Is JSI compatible with older React Native versions?

JSI requires React Native 0.68 or newer, but became stable and default in 0.76. Projects below 0.68 need major upgrades to use JSI and TurboModules.

Can I mix TurboModules with legacy bridge modules?

Yes. TurboModuleRegistry automatically falls back to bridge modules if TurboModule versions aren't available. This makes gradual migration possible without breaking existing functionality.

Do TurboModules work with Expo?

Expo supports the New Architecture starting in SDK 50. Set newArchEnabled flags in your Expo config. Managed workflow apps can use custom development builds to include TurboModules.

How much faster are TurboModules compared to bridge modules?

Benchmarks show 20-30% faster method invocation and 25-40% reduced startup time in production apps. Heavy operations like database queries and image processing see even bigger gains from direct memory access.

What happens if I don't migrate to the New Architecture?

Legacy architecture still works but misses performance improvements and future features. React Native will maintain backward compatibility for several years, but new libraries increasingly require the New Architecture.

Can TurboModules access device hardware directly?

Yes. TurboModules provide full access to native platform APIs including camera, sensors, Bluetooth, and file systems. JSI makes these interactions faster and more efficient than bridge-based modules ever could.

Does the New Architecture increase app size?

App size increases slightly due to additional C++ libraries, typically 1-2 MB per platform. The performance benefits far outweigh this minimal size increase for most applications.

Making Your Decision

JSI and TurboModules represent the future of React Native. Apps built with the New Architecture deliver performance that matches native development while keeping JavaScript's productivity advantages.

The startup time improvements alone justify migration for most production apps. Add in better frame rates, lower memory use, and improved type safety, and the case becomes overwhelming.

Start small. Enable the New Architecture in a development branch. Convert one module and measure the impact. Most teams find the migration smoother than expected.

The React Native ecosystem fully embraced this architecture by 2025. Major libraries support it, tooling works well, and the community has solid migration guides.

Build your next feature using TurboModules. Test on real devices to see the responsiveness difference. Once you experience the performance gains, returning to bridge-based modules feels slow.

The transition period has passed. JSI and TurboModules are production-ready technologies that power millions of devices worldwide. Your users will notice the difference.

Top comments (0)