Hermes is a JavaScript engine with AOT (Ahead-of-Time) compilation, developed by Meta for React Native and optimized for mobile devices with limited memory. According to the official Meta Engineering blog (2022), Hermes reduces app startup time by 20-50% and decreases bundle size by 30-40% compared to JavaScriptCore. Unlike V8 or JSC, Hermes does not use JIT compilation on the device — all JavaScript is compiled into bytecode at build time via the Hermes CLI. This is especially important for iOS, where JIT compilation is restricted by App Store policies.
Key Takeaways
Hermes is a compact open-source JavaScript engine (MIT license) created by Meta for React Native and optimized to run on resource-constrained mobile devices. The main innovation of Hermes is abandoning JIT compilation in favor of AOT (Ahead-of-Time). During the React Native app build phase, Metro Bundler passes the compiled JavaScript to Hermes CLI, which transforms it into HBC (Hermes ByteCode) bytecode. This bytecode is executed directly by the engine without additional compilation on the device. This approach provides predictable performance: no JIT warming up, no compilation pauses, no extra battery drain. Hermes is designed with mobile device limitations in mind: small RAM (1-4 GB), limited power consumption, and the need for fast cold starts. The first public release of Hermes was in 2019, and starting with React Native 0.70 (2022), the engine became the standard on Android.
JavaScriptCore (JSC) is the standard WebKit engine used by Safari and React Native prior to version 0.70. JSC supports JIT compilation, which provides high performance for complex JavaScript operations. However, JIT requires warm-up: the first seconds of execution are slower (interpreted mode), then JIT compiles hot paths. On iOS, JIT is practically unavailable due to App Store policies (ban on dynamic code generation), so JSC on iOS works only in interpreted mode — performance drops. JSC has a larger binary size (about 10 MB) and consumes more RAM due to JIT infrastructure. Hermes does not depend on JIT, providing predictable performance immediately after startup (cold start). JSC supports the ECMAScript standard more fully (including Proxy, BigInt, Reflect), but at the cost of higher resource consumption. For React Native projects where cold start and small size are critical — Hermes is preferable. For projects with heavy JS computations (games, WebGL) — JSC may deliver higher peak performance.
| Parameter | Hermes | JavaScriptCore |
|---|---|---|
| Compilation | AOT (at build time) | JIT + Interpreted (on device) |
| Cold start | 20-50% faster | Baseline |
| Bundle size | 30-40% smaller | Baseline |
| RAM usage | 20-30% less | Baseline |
| ECMAScript | ES2020 (limitations) | ES2022+ (full) |
| iOS JIT | Not required | Unavailable (interpreted only) |
| Binary | ~3 MB | ~10 MB |
AOT compilation (Ahead-of-Time) in Hermes happens in two stages. In the first stage, Metro Bundler collects JavaScript files into a single bundle and passes it to Hermes CLI (the hermesc utility). In the second stage, hermesc parses the JavaScript AST, generates an intermediate representation HIR (Hermes Intermediate Representation), and then emits binary HBC bytecode. The result is a .hbc file that contains only bytecode without the original JavaScript. The Hermes runtime loads HBC directly, without parsing and compilation. This radically speeds up startup: instead of parsing thousands of lines of JS (async), the engine reads a precompiled binary format. AOT also reduces size: bytecode is on average 30% more compact than JavaScript AST. The downside of AOT — inability to execute eval, new Function or dynamic require at runtime — all modules must be known at build time.
# Install Hermes CLI standalone
npm install hermes-engine
# Compile JS to HBC bytecode
npx hermesc -emit-binary -out bundle.hbc bundle.js
# Bytecode statistics
npx hermesc -dump-bytecode bundle.hbc # shows HBC instructions
# Original JS vs HBC size
wc -c bundle.js # 2,300,000 bytes
wc -c bundle.hbc # 1,450,000 bytes (37% reduction)
The performance of Hermes is measured by three key metrics: Time-To-Interactive (TTI), APK/IPA size, and RAM consumption. According to Meta data, on Android Hermes reduces TTI by 34% compared to JSC: from 4.2 seconds to 2.8 seconds on a mid-range device (Moto G7). APK size decreases by 28% thanks to compact bytecode and the absence of JIT libraries. RAM consumption is on average 22% lower under the same load — this is especially important for devices with 2-3 GB of RAM. On iOS, the gain is even more significant: since JSC cannot use JIT, Hermes provides up to 45% TTI improvement. Metrics are based on Meta's tests with the Facebook Lite app. In real projects, the gain varies: for simple screens (lists, text) Hermes gives a larger improvement, for heavy animations — a smaller one. Profiling tool: React Native Profiler + hermes profile --heap.
Hermes includes a built-in memory profiler accessible via Chrome DevTools. Connect to the app through Metro, open the Memory tab and select Hermes (JavaScript) from snapshot types. Hermes supports three snapshot types: Heap Snapshot (all objects), Allocation Timeline (object lifetimes) and Allocation Sampling (sampling profile). Hades GC reduces GC pauses to a minimum — on average one 2-5ms pause per 10 seconds of operation, compared to 10-20ms pauses for JSC over the same period.
Hades GC is the garbage collector in Hermes, designed for mobile scenarios with minimal pauses. Unlike the mark-sweep GC in JSC, Hades uses concurrent collection: the collector works in parallel with the main execution thread, stopping it only for short intervals. Hades GC divides the heap into generations: the young generation (nursery) is collected frequently and quickly (Scavenge), the old generation is collected less often with smaller pauses. The heap size is configurable: by default — 2/3 of the app's available RAM, minimum threshold — 32 MB. Hades does not use a stop-the-world approach: even a full old generation collection takes no more than 5-8ms. The collector is optimized for typical mobile scenarios: many short-lived objects (temporary strings, React fiber objects), few long-lived ones. For applications with intensive object creation (lists, animations), Hades provides smoother FPS compared to JSC.
Enabling Hermes depends on the React Native version and platform. Starting with React Native 0.70, Hermes is enabled by default for Android in new projects. For iOS, Hermes is optional. To enable on Android: in the file android/app/build.gradle set enableHermes: true in the project.ext.react.enableHermes block. For iOS: set hermes_enabled to true in the Podfile via use_react_native!(:path => config[:reactNativePath], :hermes_enabled => true). After enabling, run pod install. For existing projects, check library compatibility: Hermes does not support Proxy, eval, and some ES2021 features. Use npx react-native info to verify configuration. To switch between Hermes and JSC, change the flag and perform a clean rebuild.
// android/app/build.gradle — enable Hermes
project.ext.react = [
enableHermes: true,
cliPath: "node_modules/react-native/cli.js"
]
// iOS/Podfile — enable Hermes on iOS
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
target 'MyApp' do
config = use_native_modules!
use_react_native!(
:path => config[:reactNativePath],
:hermes_enabled => true
)
end
The main limitations of Hermes are related to the lack of JIT. Hermes does not support: Proxy and Reflect API (used in MobX, Vue, some state managers), BigInt (large numbers), Symbol.toStringTag, WeakRef and FinalizationRegistry. The eval and new Function functions throw an exception at runtime. Callbacks of Array.prototype.flat and flatMap with a this argument work with limitations. ISO 8601 date formats with timezones are not fully processed. Most of these limitations do not affect typical React Native applications: React and React Native use a limited set of ES features. If a library requires Proxy (for example, MobX 6+ with Proxy), use configure({ useProxies: false }) or choose an alternative. To check compatibility of existing code, run npx hermesc -check on your bundle — it will show the list of unsupported features.
Frequently Asked Questions
In the app console, run console.log(global.HermesInternal). If the HermesInternal object exists — the app is running on Hermes. Alternatively: console.log(global.HermesInternal?.getRuntimeProperties()) — will output the engine version and GC parameters. In Release builds, HermesInternal may be unavailable to minimize size.
Check your Podfile settings: Hermes on iOS requires New Architecture (Fabric Renderer). Set :hermes_enabled => true, run pod install --repo-update. If the project is upgrading from React Native below 0.70, check library compatibility with New Architecture. Disable Hermes if a third-party library requires JSC — change the flag to false and reinstall Pods.
No, Hermes does not affect Hot Reload / Fast Refresh. During development, Metro runs the JavaScript bundle without Hermes compilation (plain JS). Hermes bytecode is built only for Release builds. In Debug mode, standard JavaScriptCore or Hermes in interpreted mode is used. Hot Reload speed does not change when Hermes is enabled in configuration — switching occurs only at the production build stage.
Yes, starting from Expo SDK 45, Hermes is supported for managed workflow. In app.json set "jsEngine": "hermes". For bare workflow, Hermes works as in a regular React Native project. Expo Go does not support Hermes — use Expo Dev Client or EAS Build for builds with Hermes. Check library compatibility via expo doctor.
Use React Native Performance Monitor (FPS metrics) and Hermes Profiling Tools. Build two versions of the app — with Hermes and JSC — on the same device. Measure: cold start (from tapping the icon to the first interactive screen), TTI (Time-To-Interactive), APK/IPA size, and peak RAM consumption. Run tests at least 3 times for each configuration. Typical Hermes advantage: 20-40% faster startup, 15-25% less RAM.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also