How to enable Hermes Engine in an existing react native app
Benefits of Hermes Engine and why you should use it

TL;DR
Hermes is an open-source JavaScript engine optimized for running React Native apps on Android. For many apps, enabling Hermes will result in improved start-up time, decreased memory usage, and smaller app size.
What can you expect from Hermes:
- Reduce the time it takes for the app to become usable, called time to interact (TTI)
- Lower bundle size (on Android, APK size)
- Lower memory utilization
Move to Getting started 🚀 section to start the migration to Hermes!
Introduction
Migrating a previously existing project can be a challenge, in this article I will share the process that takes to migrate our current application to Hermes, I will share some explanation to develop the mental maps of how a traditional javascript engine works and understand the true benefit of Hermes. I will also include solutions and explanations to possible compatibility errors I faced such as mobx with MST.
This will result in an increasing performance and lower application size running specifically with mobile applications that is primarily with react native on Android because on iOS you are forced to use V8 engine.
Why you should use Hermes
The three main architecture Facebook focus on improving are:
- Ditching the JIT (just-in-time) compiler.
- Precompiling the JavaScript source code.
- Adapting garbage collection to mobile OS constraints.
Ditching the JIT
What does a traditional engine does?
I am going to talk specifically about V8, the first thing the engine does is parse your source code into an Abstract Syntax Tree (AST). At this point, an interpreter starts processing the language that you are currently executing. For many years, JavaScript was just an interpreted language, so, if you ran the same code in your JavaScript 100 times, the JavaScript engine had to take that code and convert it to machine code 100 times. This is wildly inefficient.
The Chrome browser introduced the firstJavaScriptJIT compiler in 2008. A JIT compiler contrasts with an Ahead-of-Time (AOT) compiler in that it compiles your code as it is running that code. Whenever it sees code executed a few times, it marks that code as “warm” for JIT compilation. The compiler then compiles a bytecode representation of that JavaScript”stub”code. This bytecode is typically an Intermediate Representation (IR), one step removed from the machine-specific assembly language. This work is performed by a just-in-time (JIT) compiler.

This step delays the start of JavaScript execution. To skip this step, Hermes uses an ahead-of-time compiler.
Precompiling the JavaScript source code
Hermes uses an ahead-of-time compiler, which runs as part of the mobile application build process. As a result, more time can be spent optimizing the bytecode, so the bytecode is smaller and more efficient. Whole-program optimizations can be performed, such as function deduplication and string table packing. The bytecode is designed so that at runtime, it can be mapped into memory and interpreted without needing to eagerly read the entire file.

Adapting garbage collector
Operating systems kill applications that use too much memory. When apps are killed, slow restarts are required and background functionality suffers. Hermes adapting garbage collection aids to reduce the overall virtual memory consumption by implementing on-demand allocation in non-contiguous chunks that can be moved around and returned to the OS when no longer needed.
The following are the features of the garbage collector :
- On-demand allocation: Allocates VA (virtual address) space in chunks only as needed.
- Noncontiguous: VA (virtual address) space need not be in a single memory range, which avoids resource limits on 32-bit devices.
- Moving: Being able to move objects means the memory can be defragmented and chunks that are no longer needed are returned to the operating system.
- Generational: Not scanning the entire JavaScript heap reduces time.
Getting started 🚀
Prerequisites
First, ensure you’re using at least version 0.60.4 of React Native.
If you have an existing app based on an earlier version of React Native, you will have to upgrade it first. See Upgrading to new React Native Versions for how to do this. Make specially sure that all changes to
android/app/build.gradle
have been applied, as detailed by the React Native upgrade helper. After upgrading the app, make sure everything works before trying to switch to Hermes.
Note for Windows users:
Hermes requires Microsoft Visual C++ 2015 Redistributable
Instructions:
Edit your android/app/build.gradle
and apply the following changes
project.ext.react = [
entryFile: "index.js",
- enableHermes: false // clean and rebuild if changing
+ enableHermes: true // clean and rebuild if changing
]
If you’re using ProGuard, you will need to add these rules in proguard-rules.pro
-keep class com.facebook.hermes.unicode.** { *; }-keep class com.facebook.jni.** { *; }
If you’ve already built your app at least once, clean the build:
$ cd android && ./gradlew clean
You should now be able to develop and deploy your app as normal:
$ npx react-native run-android
You should be able to start using Hermes now.
Test if Hermes is enabled
A HermesInternal
global variable will be available in JavaScript that can be used to verify that Hermes is in use:
const isHermes = () => global.HermesInternal != null;
If you created your app from scratch you can se some conditional rendering of a string like in the official documentation instructions, based on the isHermes() function like this:

Important note: Since my project had been built previously, I did not have the typical example in the screenshot above, as a consequence I was trying to print the value using console.log with the global debugger. I realized later that in order to see the log from the console, you must enable debugging mode. After activating debugging, the browser executes the js code. The engine is the V8 engine of the browser, not Hermes. When debug mode is off, Android phone executes js code.
To see the benefits of Hermes, try making a release build/deployment of your app to compare. For example:
$ react-native run-android --variant release
Problems with Proxies integrations:
If you use a solution for the state management like redux or mobx (specially for mobx state tree), you might run into some errors at compile time during the Hermes integration due to the presences of Proxies in their source code. This was one of the errors that I ran into with the current integration. The problem is that the Hermes package by default does not support the Proxy conversion, if you do not know what a Proxy is in Javascript this article contains a very good explanation.
The solution, was to manually add the 0.5.2-rc1 version of the Hermes Engine that support Proxies.
$ yarn add hermes-engine@0.5.2-rc1
And we are done!
Would you add something? Please leave a comment or give your feedback. Clap 👏 and share. This will help me improve the content and motivate me to do more. I invite you to read another of my articles.