CLI tool
facebook/hermes avatar
facebook/hermes

facebook/hermes: the JavaScript engine behind React Native's start-up time

A JavaScript engine optimized for running React Native.

11,329 stars874 forksJavaScriptMIT

At a glance

What is it?
Hermes trades just-in-time compilation for ahead-of-time bytecode so React Native apps can start faster. Here is what it does, how to build the CLI from source, and where it stops being the right engine.
Who is it for?
Adopt Hermes if you ship a React Native app and care about time-to-first-render; the README's own instruction is to enable it through the React Native docs rather than build it yourself, and to match each Hermes release to its RN version, since a mismatch can crash the app. Do not adopt it if you need a general-purpose embeddable engine for a browser-like workload or a JIT, and do not build from source unless you are hacking on the engine or integrating a custom build.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Hermes solves: start-up cost, not peak throughput

Most JavaScript engines are built around a just-in-time compiler. They parse source at run time, interpret it, and promote hot functions to optimized machine code as the program runs. That design rewards long-running workloads, where the warm-up cost is amortized. A React Native app has the opposite profile. It loads a bundle once, renders, and then sits mostly idle waiting for user input. The parse-and-optimize work happens on the critical path, before the first frame is drawn.

Hermes attacks that path directly. The README describes it as "a JavaScript engine optimized for fast start-up of React Native apps" with "ahead-of-time static optimization and compact bytecode." The compilation step moves out of the app's launch and into the build. What ships on the device is bytecode rather than source, so the engine spends less time turning text into something executable. The intended audience is narrow and clear: teams shipping React Native, and people who want to modify the engine itself. If you are not in one of those two groups, the README is explicit that you do not need the source at all.

Ahead-of-time bytecode and what the repository layout implies

The mechanism visible from the repository is a compiler plus a virtual machine. The top-level entries include lib/, include/, API/, tools/ and unittests/, which is the shape you would expect from a C++ engine that is both a library and a set of command-line tools. The build produces CLI tools, and the README's own example runs JavaScript through ./bin/hermes. That binary is the compiler and the runtime in one: it can execute a script, and it can emit the compact bytecode that a React Native app ships.

The static optimization happens before the code reaches the device. That is the central trade-off, and the README does not hide it. Ahead-of-time work cannot see the values that will actually flow through the program at run time, so it cannot make the speculative bets a JIT makes. The engine gives up peak steady-state performance in exchange for a shorter path to the first frame. For a chat app or a settings screen, that is the right exchange. For a long-running compute loop, it is not.

The default branch is static_h, which is worth noting because it is not the branch name most people would guess for a JavaScript engine. The repository also carries android/, armhf/, hermes-engine.podspec and npm/ entries, which reflect that Hermes is delivered as a native dependency for both Android and iOS builds rather than as a standalone runtime you install once.

Building the Hermes CLI from source and running a first script

The README is upfront that most readers should not do this. It says that if you only want pre-built Hermes in a React Native app, you do not need the source and should follow the React Native instructions to enable Hermes instead. The build steps below are for hacking on the engine or integrating a custom build.

The documented prerequisites are a typical native development setup for your OS, plus cmake and Ninja. On macOS or Linux the README gives this sequence, which clones the repository and configures a debug build:

bash
mkdir hermes_workingdir
cd hermes_workingdir
git clone https://github.com/facebook/hermes.git
cmake -S hermes -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug
cmake --build ./build

On Windows the README uses a Git Bash shell and a Visual Studio generator, and it passes -c core.autocrlf=false to the clone so line endings are left alone:

bash
git -c core.autocrlf=false clone https://github.com/facebook/hermes.git
cmake -S hermes -B build -G 'Visual Studio 16 2019' -A x64
cmake --build ./build

After the build finishes you are in a directory containing the CLI tools. The README's first real use pipes a small script into the engine:

bash
echo "'use strict'; function hello() { print('Hello World'); } hello();" | ./bin/hermes

The script defines a function, calls it, and uses print, which the README's example treats as available in the CLI environment. The expected output is the text Hello World. If you want the full dependency list and the build options the README omits, it points to doc/BuildingAndRunning.md, and for putting a custom build into an app it points to doc/ReactNativeIntegration.md.

Version matching is the failure mode that actually bites

The README carries a warning that deserves more weight than its placement suggests. Each Hermes release targets a specific React Native version, and the rule of thumb is to follow the releases strictly. The stated consequence of a mismatch is, in the README's words, an instant crash of your app in the worst case. That is not a soft degradation. It is a startup failure.

This shapes how you should treat upgrades. Hermes is not a library you bump independently and test at leisure; it is coupled to the React Native release you are on. The recent release list shows the pattern: v0.13.0 is labelled for RN0.75.x, v0.11.0 is labelled for RN0.68.x, and v0.12.0 carries no RN label at all. The gaps between releases are wide, which means the version you get is largely decided by the React Native version you chose, not by a separate Hermes upgrade decision.

The other limitation is scope. Hermes is optimized for start-up of React Native apps. The README makes no claim about server-side JavaScript, browser embedding, or workloads that benefit from a JIT. If your use case is a Node.js service, this is the wrong tool and the repository does not pretend otherwise.

How Hermes differs from V8 in approach

V8 is the obvious comparison, and the difference is architectural rather than incremental. V8 ships source or bytecode and compiles hot code at run time with a tiered JIT. Its design assumes the process will live long enough for that investment to pay back, which is why it performs so well in browsers and in Node.js. Hermes moves compilation earlier and accepts a lower ceiling in exchange for a lower floor.

That single choice explains most of the downstream differences. Bytecode that is prepared at build time can be made compact, which matters for app download size and for how much has to be read from storage at launch. It also means the engine does not need to carry a JIT compiler and its supporting machinery into the app binary. The cost is that any optimization requiring run-time type feedback is off the table.

The practical consequence for a team is that Hermes is not a drop-in replacement for V8 in an arbitrary embedding. It is a component of the React Native toolchain. Choosing it is really choosing the React Native default, and the interesting question is not whether Hermes beats V8 in general but whether your app's start-up time matters more than its steady-state throughput.

Licence, maintenance and upgrade cost

Hermes is MIT licensed, and the README links to the LICENSE file at the repository root. MIT is permissive: it allows use, modification and redistribution with the licence and copyright notice preserved. That is a low-friction position for a mobile app dependency, though anyone shipping a modified engine should read the actual licence text rather than a summary, and legal questions belong with a lawyer.

The repository is not archived, and the last push was on 2026-09-19, two days before this writing. That is current activity. The release cadence is a different matter: the listed releases run from 2022 to 2024, with v0.13.0 in August 2024, so the tagged releases move much more slowly than the default branch. If you depend on a tagged release, plan around that cadence rather than around commit activity.

The upgrade cost is the version coupling described above. Because each release targets a React Native version, upgrading Hermes usually means upgrading React Native, which means re-testing the app rather than just swapping a dependency. For most teams the honest accounting is that Hermes is a fixed cost of the React Native stack, not a component with its own upgrade treadmill.

Editorial conclusion

Adopt Hermes if you ship a React Native app and care about time-to-first-render; the README's own instruction is to enable it through the React Native docs rather than build it yourself, and to match each Hermes release to its RN version, since a mismatch can crash the app. Do not adopt it if you need a general-purpose embeddable engine for a browser-like workload or a JIT, and do not build from source unless you are hacking on the engine or integrating a custom build. Before committing, verify which Hermes version your React Native release pins, and read doc/BuildingAndRunning.md and doc/ReactNativeIntegration.md rather than relying on the short README build steps.

Frequently asked questions

How do I install Hermes for a React Native app?

The README says that if you only want pre-built Hermes in a new or existing React Native app, you do not need the source and should follow the React Native instructions to enable Hermes. Building from source is only for hacking on the engine or integrating a custom build.

How do I build the Hermes CLI from source?

The README documents a cmake and Ninja build: clone the repository, configure with -DCMAKE_BUILD_TYPE=Debug, then build. On Windows it uses a Visual Studio generator from a Git Bash shell and passes -c core.autocrlf=false to the clone.

How do I run a JavaScript file with Hermes?

Once the CLI tools are built, the README pipes a script into the engine with echo and ./bin/hermes. Its example defines a function that calls print and expects Hello World as output.

Official sources

  1. facebook/hermes on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/facebook-hermes.svg)](https://hysenlabs.com/projects/facebook-hermes)