Introduction: Why Hermes Is the Default Engine for React Native
Hermes is Meta's open-source JavaScript engine purpose-built for React Native — since React Native 0.70, Hermes is the default engine on both Android and iOS. Unlike general-purpose engines like JavaScriptCore (JSC) or V8, Hermes is specifically optimised for mobile constraints: limited memory, slow storage I/O, and battery sensitivity.
The key innovation is Ahead-of-Time (AOT) bytecode compilation — JavaScript is compiled to optimised bytecode during the build step rather than at runtime. This eliminates JIT compilation overhead on app launch, delivering dramatically faster startup times and lower memory consumption, particularly impactful on mid-range and low-end Android devices that represent the majority of the global mobile market.
AOT Compilation: How Hermes Bytecode Works
Understanding the Hermes compilation pipeline:
- Build-Time Compilation: Metro bundler produces a JavaScript bundle → Hermes compiler (
hermesc) transforms it into optimised bytecode (.hbcfiles) during the build step. No JavaScript parsing or compilation happens at runtime. - Bytecode Format: Hermes bytecode is a compact binary format with register-based instruction set — smaller than source JavaScript and faster to load from disk. The
.hbcfile is memory-mapped directly, avoiding parse-time heap allocation. - Startup Elimination: Traditional engines (JSC, V8) parse JavaScript source → generate AST → compile to bytecode → optimise hot paths at runtime. Hermes skips all of these steps by shipping precompiled bytecode — TTI (Time to Interactive) improvements of 25–50% on real devices.
- Size Optimisation: Hermes bytecode is typically 10–30% smaller than equivalent minified JavaScript source code — reducing APK/IPA size and improving download-to-first-launch conversion rates on app stores.
- Source Maps: Hermes generates source maps during compilation — stack traces in production crash reports map back to original TypeScript/JavaScript source lines for accurate debugging.
Integration: Enabling Hermes on Android and iOS
Configure Hermes for both platforms:
- Android Setup: In React Native 0.70+, Hermes is enabled by default. For older versions, set
hermesEnabled: trueinandroid/app/build.gradle. Runcd android && ./gradlew cleanthen rebuild — Hermes replaces JSC as the JavaScript runtime. - iOS Setup: Hermes on iOS ships as a pre-built XCFramework — enable via
:hermes_enabled => truein your Podfile, thencd ios && pod install. Hermes on iOS delivers the same AOT compilation benefits with Apple Silicon-optimised bytecode. - Verification: Check Hermes is active with
global.HermesInternal !== undefined— returns true when Hermes is the active engine. In development, the Metro DevTools connection panel shows "Hermes" as the engine identifier. - Expo Integration: Expo SDK 48+ uses Hermes by default — no manual configuration required. Custom dev clients (
expo-dev-client) automatically include Hermes with full debugging support. - Build Variants: Configure separate build variants for Hermes and JSC — useful during migration to run A/B performance comparisons before fully committing to Hermes across your release pipeline.
Memory Optimisation: Garbage Collection and Heap Management
Hermes's memory management is optimised for mobile constraints:
- GenGC Garbage Collector: Hermes uses a generational, moving garbage collector — short-lived objects (common in React renders) are collected quickly in the young generation. Long-lived objects promote to the old generation with less frequent collection cycles.
- Memory-Mapped Bytecode: The
.hbcfile ismmap()-ed directly into memory — the OS can page out unused bytecode segments under memory pressure without requiring Hermes to re-parse JavaScript source code. - Lazy Compilation: Hermes supports lazy function compilation — functions are only fully compiled when first called, reducing initial memory footprint for large codebases with many rarely-used code paths.
- Real-World Reductions: E-commerce apps report 30–50MB memory reduction after Hermes migration — background memory consumption drops significantly, reducing OOM (Out-of-Memory) kills on Android devices with 2–3GB RAM.
- Heap Snapshots: Use
HermesInternal.getInstrumentedStats()to monitor heap size, GC frequency, and allocation rates in production — identify memory leaks by comparing heap snapshots across navigation flows.
Debugging and Profiling with Hermes
Full-featured debugging toolchain for Hermes:
- Chrome DevTools Protocol: Hermes implements the Chrome DevTools Protocol (CDP) — connect directly from Chrome DevTools or VS Code for breakpoint debugging, step-through execution, and variable inspection without Flipper as an intermediary.
- Flipper Integration: Meta's Flipper desktop app provides Hermes-specific panels — React DevTools for component tree inspection, network inspector for API debugging, and Hermes profiler for CPU sampling and heap analysis.
- CPU Profiling: Hermes CPU profiler generates Chrome trace format files — visualise function execution times, identify hot paths, and detect unnecessary re-renders in flame chart view. Profile both JavaScript and native bridge calls.
- Sampling Profiler:
HermesInternal.enableSamplingProfiler()captures production performance data without significant overhead — analyse function-level CPU time distribution to optimise critical paths. - LogBox Integration: Hermes provides enhanced error messages with accurate stack traces — TypeScript source maps ensure LogBox warnings and errors reference original source code lines rather than compiled bytecode offsets.
Transform Your Publishing Workflow
Our experts can help you build scalable, API-driven publishing systems tailored to your business.
Library Compatibility and Migration Strategies
Manage third-party library compatibility during Hermes adoption:
- ECMAScript Support: Hermes supports ES6+ features including classes, arrow functions, destructuring, async/await, and optional chaining. Some newer proposals (e.g.,
IntlAPI,Proxy) have partial support — check the Hermes compatibility table for your target version. - Polyfill Strategy: For missing APIs, use targeted polyfills —
@formatjs/intl-numberformatfor Intl.NumberFormat,proxy-polyfillfor basic Proxy support. Configure Metro to inject polyfills before app code withserializer.getModulesRunBeforeMainModule. - Native Module Testing: Libraries with native modules (Reanimated, Gesture Handler, Maps) are fully compatible with Hermes — test animation performance specifically, as Hermes worklet execution differs from JSC in timing characteristics.
- Crypto Libraries:
react-native-cryptoandethers.jsrequire Hermes-compatible builds — usereact-native-quick-cryptofor native crypto performance or polyfillcrypto.getRandomValuesfor basic use cases. - Gradual Migration: Enable Hermes on staging builds first → run full regression test suite → monitor crash reports for 1 week → enable on production. Use feature flags to roll back to JSC if critical issues emerge.
Production Benchmarks: Real-World Performance Data
Measured performance improvements across production apps:
- Startup Time: Cold start reduced by 25–40% across tested apps — an e-commerce app went from 3.2s to 1.9s TTI on a Pixel 4a. Budget Android devices (Redmi Note series) show even larger improvements due to eliminated JIT compilation overhead.
- Memory Usage: Average 30MB reduction in runtime memory — critical for apps targeting markets where 2–3GB RAM devices dominate (India, Southeast Asia, Africa). Fewer OOM kills reduce crash rates by 15–20%.
- APK Size: Hermes bytecode reduces JavaScript payload by 15–25% compared to minified source — combined with Hermes engine being smaller than JSC, total APK size decreases by 5–10MB for large apps.
- Battery Impact: Eliminated JIT compilation reduces CPU cycles during app launch — battery consumption during startup sequences drops measurably, improving user experience on devices with degraded batteries.
- Animation Performance: Frame rates remain consistent at 60fps with Hermes — Reanimated 3 worklets execute on the UI thread regardless of JS engine, so animation-heavy apps see startup benefits without animation regression.
Hermes and React Native New Architecture, and MDS Services
Hermes is integral to React Native's New Architecture:
- JSI (JavaScript Interface): Hermes natively supports JSI — synchronous, direct communication between JavaScript and native code without the JSON serialisation overhead of the old bridge. JSI enables Turbo Modules and Fabric rendering.
- Turbo Modules: Lazy-loaded native modules with JSI bindings — modules initialise only when first accessed, reducing startup time further. Hermes's bytecode precompilation complements Turbo Module lazy loading for maximum startup optimisation.
- Fabric Renderer: The new rendering system leverages JSI for synchronous layout measurement — Hermes's efficient bytecode execution ensures smooth concurrent rendering with React 18 Suspense and transitions.
- Static Hermes (Experimental): Meta is developing Static Hermes — an AOT compiler that produces native machine code instead of bytecode, promising near-native execution speed for compute-intensive JavaScript code.
MDS provides React Native performance optimisation services — from Hermes migration and New Architecture adoption through custom native module development, production profiling, and cross-platform performance benchmarking for enterprise mobile applications.




