The release of React Native 0.64 introduced full opt-in support for Hermes on iOS. This promises to be a major shift in the React Native mobile app development ecosystem.
In this tutorial, we’ll explore the benefits of using Hermes as the JavaScript engine for your React Native application and demonstrate how to build and run a React Native application using Hermes. We’ll walk you through the necessary steps to get your React Native application up and running with Hermes as the JavaScript engine.
Here’s what we’ll cover:
- New in React Native 0.64: Hermes support for iOS
- What is Hermes?
- Why is performance optimization important?
- Using Hermes in React Native
- Enabling Hermes on Android
- Enabling Hermes on iOS
- Building a React Native app with Hermes support
- Debugging a React Native app in Chrome
New in React Native 0.64: Hermes support for iOS
The release of React Native 0.64 announcement came with drop-in support for Android API levels 16-20 due to low usage. Hermes is the headline feature that is shipped with this release. Other changes include enabling inline require for Metro bundler, Hermes traces with Google Chrome, Hermes with proxy support, and other changes for React 17. Let’s explore a few of these changes that may affect how mobile applications are built in React Native going forward.
Hermes support for Android has been active for a while. With the opt-in support for iOS in React Native 0.64, you can now build a fast, efficient, and performant proof application.
What is Hermes?
Hermes is an open-source JavaScript engine that is designed to optimize performance by reducing app launch time and precompiling JavaScript into efficient bytecode.
Building an application with Hermes is pretty straightforward. It only requires three lines of code to configure Hermes and get up and running:
use_react_native!( :path => config[:reactNativePath], :hermes_enabled => true )
Note that Hermes on iOS is still in its infant stage and has yet to gain full stability. If you run into bugs, you can visit the official React Native GitHub repo to raise an issue.
Why is performance optimization important?
Whether your app is still in development or deployed to production, performance is one of the key attributes to look out for when building a mobile application. Hermes bridges the performance gap in React Native.
Here’s how Hermes works behind the scenes:
The left pane consists of code input on the Hermes playground while the right pane displays the output as bytecode. The load time is shown as well. In this case, the sum function took 60ms to compile and run.
Using Hermes in React Native
For this tutorial, we’ll show you how to build a fairly simple React Native application that displays weather information from mock data. The app will display current weather forecasts in the US.
The finished application should look like this:
Before you begin, ensure that you’re using React Native 0.64.
To create a new React Native project, navigate to your working directory via the terminal and copy/paste the code below:
npx react-native init WeatherApp
Enabling Hermes on Android
To enable Hermes on Android, open your newly create project in you preferred code editor and update your android/app/build.gradle
file to look like this:
project.ext.react = [ entryFile: "index.js", enableHermes: true ]
Next, run the project on Android with the code below:
$ npx react-native run-android
Enabling Hermes on iOS
To enable Hermes on iOS, open your newly created project in your preferred code editor and update your Podfile
, set hermes_enabled
. See code snippet below:
use_react_native!( :path => config[:reactNativePath], :hermes_enabled => true )
Next, run pod install.
$ cd ios && pod install
Finally, run your iOS app with the code below:
$ npx react-native run-ios
Your app should look like this:
You’ll notice that Hermes is identified as the app’s engine in the top-right. This indicates that Hermes is actively running.
Now that we’re done with the Hermes setup, let’s proceed to build our application.
Building a React Native app with Hermes support
First, clone the starter file from Github
:
$ git clone https://github.com/emmanueletukudo/herms-starter.git
Replace the content in the Home
screen with the code below:
import React from "react"; import {StyleSheet, Text, Image, View, TouchableOpacity, FlatList} from "react-native"; import axios from "axios"; import {data, icons} from "../constants/" const Home = () => { const [weatherData, setWeatherData] = React.useState([ { id: 0, city: "New York", temp: 283.88, main: "Clouds", icon: icons.thunder, description: "overcast clouds", }, { id: 1, city: "San Francisco", temp: 285.52, main: "Rain", icon: icons.rainy, description: "broken clouds", }, { id: 2, city: "Chicago", temp: 283.88, main: "Rain", icon: icons.metro, description: "overcast clouds", }, ]); function renderWeather(item, index){ return( <TouchableOpacity style={styles.weatherContainer} > <Text style={styles.city}>{item.city}</Text> <Image source={item.icon} resizeMode="cover" style = {styles.icon} /> <View style={styles.weatherDetailsWrapper}> <Text style={styles.main}>{item.main}</Text> <Text style={styles.temp}>{item.temp}</Text> </View> </TouchableOpacity> ) } return( <View style={styles.constainer}> <FlatList horizontal showsHorizontalScrollIndicator={false} data={weatherData} keyExtractor={item => item.id.toString()} renderItem ={({item, index}) => renderWeather(item, index)} /> </View> ) } const styles = StyleSheet.create({ constainer: { flex: 1, backgroundColor: "#000", alignItems: "center", padding: 70, }, weatherContainer: { width: 350, justifyContent: "center", marginHorizontal: 14, backgroundColor: "#000", }, hello:{ flex: 1, alignItems: "center", fontSize: 12, fontWeight: "700", color: "#000" }, weatherDtails1:{ flex: 1, justifyContent: "center", marginTop: "20%", borderRadius: 10, marginRight: 15, paddingRight: 12, paddingBottom: 12, }, temp: { color: "#ffffff", fontSize: 14, fontWeight: "700", }, main:{ color: "#ffffff", fontSize: 14, marginTop: 15 }, city:{ color: "#ffffff", fontSize: 40, fontWeight:"700" }, weatherDetails: { fontSize: 17, fontWeight: "400", }, weatherDetailsWrapper: { flexDirection: "column", alignContent: "center", marginTop: "40%", }, icon: { top: "10%", width: 200, height: 200, } }) export default Home;
The code is self-explanatory. We have three segments: the mocked data with the React useState
hook, the function that renders the data into a React component, and code that renders the data in the Home
component using React Native FlatList
. You could take the same approach to get actual data from an API, but that’s beyond the scope of this tutorial.
Debugging a React Native app in Chrome
Hermes has support for debugging JavaScript via Chrome DevTools by implementing the Chrome inspector protocol. Chrome connects to Metro through the port it is currently listening to, so you need to know the port where Metro is listening. Metro listens on port 8181 by default, so you can access your app via the browser using http://localhost:8081
.
Once you figure out the port your app is running on, open a new tap on Chrome and type chrome://inspect
. Click the Configure… button to add your app Metro server address (e.g., http://localhost:8081
).
Add the address on the modal that pops up:
You should now be able to debug your React Native app using Chrome DevTools. To access the debugger, click Inspect.
Conclusion
Performance optimization for mobile apps just got a lot easier in React Native, thanks to the lightweight JavaScript engine Hermes.
You can read more about Hermes in the official documentation.
LogRocket: Instantly recreate issues in your React Native apps.

LogRocket is a React Native monitoring solution that helps you reproduce issues instantly, prioritize bugs, and understand performance in your React Native apps.
LogRocket also helps you increase conversion rates and product usage by showing you exactly how users are interacting with your app. LogRocket's product analytics features surface the reasons why users don't complete a particular flow or don't adopt a new feature.
Start proactively monitoring your React Native apps — try LogRocket for free.
Hi, thanks so much for this article. Really clean and helpful. We are trying to use this technique in our app, but for some reason regardless of the configuration, the code does not compile into bytecode when hermes is enabled. Any idea why that might be?