meta/hermes(新しいタブで開きます)
主要言語: JavaScript
A JavaScript engine optimized for running React Native.
- star 数
- 11,406
- watcher 数
- 139
- fork 数
- 895
- issue 数
- 290
- 最終更新
- 2026/10/31
主要言語: JavaScript
A JavaScript engine optimized for running React Native.
Hermes is a JavaScript engine built for fast start-up and low memory use. Its whole design centers on compiling JavaScript ahead of time: apps ship compact bytecode, or optionally native code, and the engine does as little work as possible when they launch. Hermes was created for React Native, where it is the default engine. It also runs standalone or can be embedded as a library in other programs.
Most engines parse and compile JavaScript on the user's device, every time the app starts. Hermes moves that work to build time. The compiler parses, analyzes and optimizes the entire program once, and emits bytecode that the engine can memory-map and start executing immediately. Start-up cost, memory and binary size all benefit, and the optimizer can see the whole program instead of one function at a time.
In practice this means:
.js files can
be run directly during development. It is not the intended production path.eval() and new Function() are supported for small things. They run
the compiler at runtime. Code passed to eval sees the global scope only;
giving it access to the enclosing function's locals would force the
compiler to pessimize every function, so that is deliberately left out.Hermes can execute JavaScript in four ways, and they can be mixed freely within one runtime.
shermes tool compiles JavaScript
ahead of time all the way to native code, with no interpreter involved.An app can ship some code as native, some as bytecode, and generate some at runtime, and the JIT will pick up hot functions from the latter two.
Hermes is gaining the ability to use type annotations to compile JavaScript to much faster code. This is under active development and not ready for use. Both Flow and TypeScript syntax are being supported, to different degrees. Flow is the more static-typing-friendly of the two, so TypeScript is currently converted to Flow by an AST pass contributed by Amazon. That is an implementation detail and may change; TypeScript support is a priority.
Neither the Flow checker nor the TypeScript compiler guarantees that the annotations are true at runtime. Both accept this program, for example:
const a: number[] = []; const n: number = a[0]; // the type says number, the value is undefined
A typed compiler has to strengthen the language semantics until the types
are actually true. In this example, typed Hermes range-checks array indexing
and throws on out-of-bounds access, so a[0] can never produce a value that
contradicts its type. Where a value of unknown type flows into a typed one,
for example from any or from untyped code, the compiler inserts a checked
cast, which throws at runtime if the value is not of the expected type. With
those guarantees in place, the generated code can rely on the types.
TypeScript is less friendly to static compilation than Flow because its typing is structural, and it is unsound in more places. This program type-checks in TypeScript and fails at runtime; Flow rejects it because object properties are invariant:
class Animal {} class Dog extends Animal { bark() {} } class Cat extends Animal {} const d: { pet: Dog } = { pet: new Dog() }; const a: { pet: Animal } = d; // TypeScript accepts, Flow rejects a.pet = new Cat(); d.pet.bark(); // d.pet is a Cat: "bark is not a function"
In TypeScript a value of type Dog need not be an instance of Dog at all;
any object with the same shape qualifies. A compiler can therefore not derive
an object layout from a class, which is exactly what makes typed code fast.
See doc/TypedLanguage.md for the current state.
Independently from this, TypeScript can already be run in untyped, unsound mode: the type annotations are stripped and the result is treated as plain JavaScript. See doc/typescript-stripping.md.
Hermes can also compile JavaScript ahead of time to native code, using the
shermes tool. It works both on ordinary untyped JavaScript and on typed
JavaScript, where the latter produces much better native code.
"Static Hermes" was the code name for an umbrella project, developed on the
static_h branch, to add static typing and optional native compilation to
Hermes. The branch then became the main development line and gained the JIT,
modern ECMAScript features, and a large amount of unrelated work. It is not a
separate engine; it is Hermes.
Hermes releases had always been numbered 0.x. When the static_h line was
judged ready, its releases moved to a new scheme built from the branch date and
bytecode version (for example 260318099.0.0), and React Native calls it
Hermes V1 to distinguish it from the legacy line on the main branch.
See doc/Branches.md.
You need a C++17 compiler, CMake, Ninja and Python. Clang is strongly recommended; gcc is supported but produces noticeably worse code. On Ubuntu:
apt install clang build-essential cmake git ninja-build python3 tzdata libreadline-dev
Clone and build the two command line tools, hermes (compile to bytecode, run
bytecode or source) and shermes (compile to native):
git clone https://github.com/facebook/hermes.git cmake -S hermes -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ cmake --build build --target hermes shermes
Run a script from source, then the way apps do it, from bytecode:
echo "print('Hello from Hermes');" > hello.js build/bin/hermes hello.js build/bin/hermes -emit-binary -out hello.hbc hello.js build/bin/hermes hello.hbc
Compile the same script to a native executable:
build/bin/shermes -O -o hello hello.js ./hello
Everything else, including macOS, Windows, release builds and running the test suites, is in doc/BuildingAndRunning.md.
Integration documentation is thin today and will grow. These are the starting points:
shermes can be built to Wasm the same way. See
doc/Emscripten.md.Contributions are welcome. The preferred way to add functionality is a JSI extension: extensions are written against the stable JSI API rather than engine internals, so they are safer to write and do not break when the engine changes. Read CONTRIBUTING.md for the development process and how to propose changes.
This project follows the Meta Code of Conduct. Hermes is MIT licensed.