Bringing Hermes to iOS in React Native 0.64

For a long time Hermes was exclusive to Android - it was optimized for running React Native apps on Android only.

In the last few months, we’ve worked really hard with teams at Facebook and Microsoft to bring Hermes to iOS. It’s part of the latest React Native 0.64 release which we contributed to.

React Native 0.64 is now available! Lots of exciting improvements, the largest of which is the support @callstackio added for Hermes on iOS!https://t.co/DuwFWHYui8

— React Native (@reactnative) March 12, 2021

Today we’d like to share with you the steps we took here, at Callstack, to make it all possible. We also have a series of benchmarks ready to better demonstrate Hermes performance compared to JSC in the context of React Native.

In order to outline the journey to Hermes iOS comprehensively, we are going to publish a series of articles:

The technical pieces will focus on implementation details, guiding you through the internals of React Native and showing how we brought Hermes to iOS. You will also find out how you can use your own custom engine yourself! 

But first things first - let’s start with talking about the beginnings of the Hermes engine.

JavaScript engine in a React Native app

Hermes is a JavaScript engine, so let’s clarify first what JS engines do. A JavaScript engine runs your application code and makes the browser perform the desired actions. All modern JS engines are designed and benchmarked to run with maximum efficiency under the browsers’ most popular use case (i.e. providing an interactive website or a web application that users can interact with).

React Native apps, despite being written in JavaScript, are different from a typical website or a web application created with React. They use neither HTML nor CSS. Instead of interacting with DOM, when building apps with React Native, a native code is shipped for both iOS and Android, respectively. The code is responsible for painting elements on a mobile screen and responding to the user’s interactions.

User expectations for mobile and web

There’s also a difference in the way users expect mobile and web applications to work. On mobile, the user tends to be more demanding when it comes to overall app performance. Applications must launch in a blink of an eye and become interactive as quickly as possible. The web, on the other hand, is a different story. The conversion is less likely to drop if a website doesn’t load instantly.

It’s no surprise then that using a JavaScript engine designed for the web makes it harder (if not impossible in certain scenarios) to meet the high standard in the mobile world - the standards that fully-native applications often reach by default.

Benefits of Hermes running on Android

That’s one of the many reasons why the Facebook team created Hermes - a JavaScript engine designed specifically for running React Native applications. At a high level, it is an engine like any other. Under the hood, it implements a lot of optimizations to make React Native run as fast as it can.

The biggest difference is that Hermes is an AOT engine. In other words, unlike most JavaScript engines, it doesn’t parse and compile your JavaScript code at runtime. It shifts all these steps to happen at a build time - when you bundle your React Native application before sending to the App Store.

data concerning Hermes on Android
Data source: Facebook engineers

Since its launch on Android, the results are remarkable! It not only offers a smooth transition for the majority of users, but also provides significant improvements to startup times together with CPU and memory consumption. For a more detailed description of Hermes on Android, check the Facebook Engineers blog.

Please keep in mind that the numbers shown in the graph are relevant for Android only and as such they do not guarantee the same improvements on iOS. In fact, as we learn in the next section, it is possible that things like an application size can actually increase a bit.

Bringing Hermes to iOS

Having the same JavaScript engine on both Android and iOS allows us to fully embrace its features. It also makes the development easier and provides a more stable experience with resolving less platform-specific issues.

Ever since the first React Native release, both platforms used JavaScriptCore - the one and only engine on iOS that was set to be used on Android as well. Theoretically, Android could have used V8 or a different engine, but that would contradict my previous point.

Now that Android has Hermes support and that’s been getting more and more popular with every React Native release, it would be great to have it on iOS as well. Only when Hermes can be run on both iOS and Android, the React Native team can take advantage of its features and start embracing its full potential.

Potential risks

The JavaScriptCore wasn’t selected as a default engine for a reason. On Apple devices, it is prohibited to ship mobile applications that run JavaScript using a different JIT engine than the one originally provided with the system.

Since Hermes is an AOT engine, these restrictions do not apply. Theoretically, it is possible to build and ship apps with Hermes provided that the Hermes engine can compile on iOS. 

However, choosing a different engine than the built-in one, has the risk of increasing the overall application size as now it has to ship its own engine rather than rely on the one available on iOS by default.

Try Hermes yourself

Hermes is now available under a flag on iOS, starting from React Native 0.64. Read my post on the official React Native blog to find out how to turn it on! I am really excited to see what you end up building on top of it!

In case you are still having doubts about using Hermes with React Native on iOS, worry not - we have run a series of benchmarks comparing Hermes and JSC on iOS together with metrics and videos. Here’s a little secret - it’s faster!

Also, we released a podcast fully dedicated to Hermes: React Native 0.64 with Hermes for iOS. Check it out to learn more about Hermes on iOS and MacOS from Microsoft and Facebook engineers.

A step-by-step guide to Hermes implementation

If you want to learn more about how we brought Hermes support to iOS, check our technical guide to Hermes compilation. We describe the entire process of compiling Hermes to work on Apple platforms, which ends up with a fully functional demo application.

Bonus point: you may use our guide as a reference when trying out your own custom engine with React Native, just in case you’re working on something tailor-made.

Looking to improve your React Native app performance? Download our Ultimate Guide to React Native Optimization. It describes best practices for optimizing app stability, resource usage, user experience or maintenance costs.

Insights

Learn more about Hermes

cover

Dec 18Article

Why You Don’t Have to Minify JavaScript Code in React Native Apps

React Native skips JavaScript minification in production because Hermes handles dead code elimination at the bytecode level. Here’s how and why it works.

cover

Dec 4Podcast

From Static Hermes to Hermes V1: The Road to Default

Nicola Corti (Meta) explains the evolution of Static Hermes into Hermes V1, the performance boosts it ships, and the (experimental) path to making it the new default engine.

cover

Nov 6Live Stream

Hermes V1: What It Is, What It Isn’t, and What’s Next

Łukasz Chludziński, Szymon Chmal, and Matt Hargett unpack Hermes V1, covering what’s new, what’s changing, and what’s ahead for React Native performance.

cover

Dec 4Article

How to Optimize Your Android App Startup Time With Hermes

Learn how to achieve better performance and optimize Android app startup time with Hermes.

cover

Jun 14Article

Technical Guide, Part 2: Integrating Hermes With React Native

Interested in the Hermes engine? Check the second part of our expert guide to find out how to integrate Hermes with React Native.

cover

May 26Article

Technical Guide, Part 1: Compiling Hermes for Apple Platforms

Want to use Hermes in your React Native app on iOS? Find out how to compile Hermes for Apple platforms. Check the first part of our expert technical guide.

cover

May 11Podcast

React Native 0.64 With Hermes for iOS

Discover how Hermes boosts React Native performance on iOS and macOS, with insights into AOT, bytecode precompilation, and the future of Hermes support.

cover

Apr 21Article

Hermes Performance on iOS

Wondering how the Hermes engine performs on iOS? We tested it on a React Native mobile app. Check the results and see how it compares to JSC.

cover

Mar 19Tutorial

The Hard Way vs. The React Native AI SDK Way: Stop Writing Custom Modules for Every Model

Learn how React Native AI uses a unified provider model to switch between cloud and on-device LLMs without rewriting application logic, enabling reliable AI experiences online and offline.

cover

Mar 12Tutorial

Build Smarter Apps: Tool Calling & AI Orchestration Explained

Learn how on-device models in React Native can call tools, interact with external APIs, and return structured outputs you can use directly in application logic.

cover

Mar 5Tutorial

MLC LLM + React Native: On-Device AI Without the Pain

Learn how to run third-party on-device LLMs in React Native using MLC LLM. Choose your models, run them efficiently across platforms, and keep a unified JavaScript API with React Native AI.

cover

Feb 24Tutorial

Intelligent Fallbacks with Apple Intelligence in React Native

Learn how to use Apple’s built-in Foundation Models in React Native apps, reduce memory usage, and enable fast, fully on-device AI with React Native AI Apple.

cover

Feb 10Tutorial

What Is the React Native AI SDK? A Complete Intro & Quickstart

Learn why on-device AI matters for React Native apps, how local LLMs behave offline, and what problems React Native AI is designed to solve from day one.

cover

Jan 29Tutorial

Implementing an Android TurboModule with Kotlin

Learn how to implement a React Native TurboModule on Android, from the TypeScript spec and Codegen to the Kotlin implementation and package registration.

cover

Jan 19Tutorial

Working with Different Threads in Swift TurboModules

Learn how JavaScript, native module, background, and main threads interact in React Native TurboModules, and how to use GCD queues to run async work safely in Swift.

cover

Jan 9Tutorial

How to Add Type-Safe Constants to Swift TurboModules

Learn how to expose typed, immutable constants from a Swift TurboModule using Codegen, and get full end-to-end type safety between native and JavaScript.

cover

Dec 30Tutorial

Adding Event Emitters to Your TurboModule in Swift

Learn how to emit native events from a Swift TurboModule and subscribe to them in JavaScript, including proper memory management and Codegen integration.

cover

Dec 22Tutorial

Writing Your First TurboModule in Swift

Learn how to build a fully working TurboModule in Swift, integrate it with Codegen, and bridge it through Objective‑C inside an Expo app.