For a long time Hermes was exclusive to Android – it was optimized for running React Native apps on Android only. Now it’s finally available on iOS as well.

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.

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 as well as 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.

abstract concept of user experience with Hermes on iOS

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 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. Check out 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!

Tags: