V8 is, I'm sure, the most used implementation of JavaScript today. Used in Chrome, (and by extension) Microsoft Edge, Node.js, etc. Safari's JavaScriptCore and Firefox's SpiderMonkey are also contenders for extremely mainstream implementations.
But what else is out there? What if I want to embed JavaScript in a C program, or a Go program, or a Rust program, or a Java program(, and so on)? Or what if I want to run JavaScript on a microcontroller? Or use it as a base for language research? It turns out there are many high-quality implementations out there.
This post describes a number of them and their implementation choices. I'm not going to cover V8, JavaScriptCore, or SpiderMonkey because they are massive and hide multiple various interpreters and compilers inside. Plus, you already know about them.
I'm going to miss some implementations and get some details wrong. Please Tweet or email me with your corrections! I'd be particularly interested to hear about pure-research; and commercial, closed-source implementations of JavaScript.
Corporate-backed
These are implementations that would make sense to look into for your own commercial, production applications.
On the JVM
- Oracle's GraalJS: compiles JavaScript to JVM bytecode or GraalVM
- Support: Full compatibility with latest ECMAScript specification
- Implementation language: Java
- Runtime: GraalVM or stock JDK
- Parser: Hand-written
- First release: 2019?
- Notes: Replaced Nashorn as the default JavaScript implementation in JDK.
- Mozilla's Rhino: interprets and compiles JavaScript to JVM bytecode
- Support: ES6
- Implementation language: Java
- Runtime: Both interpreted through custom bytecode VM and interpreted after compiling to JVM bytecode as an optimization
- Parser: Hand-written
- First release: 1998?
- Notes: Replaced by Nashorn as the default JavaScript engine on the JVM, but remains actively developed.
- Oracle's Nashorn: compiles JavaScript to JVM bytecode
- Support: ES5
- Implementation language: Java
- Runtime: compiles to JVM bytecode
- Parser: Hand-written
- First release: 2012?
- Notes: Replaced Rhino as default JavaScript implementation on JVM. Replaced by GraalJS more recently, but remains actively developed.
Embeddable
- Nginx's njs
- Support: ES5
- Implementation language: C
- Runtime: Bytecode VM
- Parser: Hand-written
- ChowJS: proprietary AOT compiler based on QuickJS for game developers
- Support: everything QuickJS does presumably (see further down for QuickJS)
- Implementation language: C presumably
- Runtime: QuickJS's bytecode interpreter but also an AOT compiler
- Parser: QuickJS's presumably
- First release: 2021
- Notes: Code is not available so exact analysis on these points is not possible at the moment.
- Artifex's mujs
- Support: ES5, probably
- Implementation language: C
- Runtime: Bytecode stack-oriented VM
- Parser: Hand-written
- First release: 2017?
- Notes: Originally part of MuPDF viewer, but now broken out. Thanks to @rwoodsmalljs for mentioning!
Embedded Systems
- Samsung's Escargot
- Support: ES2020
- Implementation language: C++
- Runtime: Bytecode VM
- Parser: Hand-written
- First release: 2017?
- Espruino
- Support: parts of ES5, ES6, ES7/8
- Implementation language: C
- Runtime: Seems like direct recursive interpreting without an AST/intermediate form
- Parser: Hand-written
- First release: 2012?
- Cesanta's Elk
- Support: subset of ES6
- Implementation language: C
- Runtime: Direct recursive interpreter without AST or bytecode VM
- Parser: Hand-written
- First release: 2019?
- Notes: It does all of this with a GC and FFI in <1400 lines of readable C code. Damn.
- Cesanta's mJS
- Support: subset of ES6
- Implementation language: C
- Runtime: Bytecode VM
- Parser: Hand-written
- First release: 2017?
- Moddable's XS
- Support: ES2018
- Implementation language: C
- Runtime: Bytecode VM
- Parser: Hand-written
- First release: 2017?
- Notes: More details at https://www.moddable.com/XS7-TC-39 and https://www.moddable.com/faq#what-is-xs.
Other
- Facebook's Hermes
- Support: ES6 with exceptions
- Implementation language: C++
- Runtime: Bytecode VM
- Parser: Hand-written
- First release: 2019?
- Qt's V4
- Support: ES5
- Implementation language: C++
- Runtime: Bytecode VM and JIT compiler
- Parser: qlalr custom parser generator
- First release: 2013
- Notes: Unclear if can be run standalone outside of Qt.
I don't know whether to put Microsoft's ChakraCore into this list or the next. So I'll put it here but note that as of this year 2021, they are transitioning it to become a community-driven project.
- Microsoft's ChakraCore
- Support: ES6, probably more
- Implementation language: C++
- Runtime: Bytecode VM and JIT on x86/ARM
- Parser: Hand-written
- First release: 2015?
Mature, community-driven
Implementations toward the top are more reliable and proven. Implementations toward the bottom less so.
If you are a looking to get involved in language development, the implementation further down on the list can be a great place to start since they typically need work in documentation, testing, and language features.
- Fabrice Bellard's QuickJS
- Support: ES2020
- Implementation language: C
- Runtime: Bytecode VM (this is a single large file)
- Parser: Hand-written (this is a single large file)
- First release: 2019
- DuktapeJS
- Support: ES5, some parts of ES6/ES7
- Implementation language: C
- Runtime: Bytecode VM
- Parser: Hand-written, notably with no AST. It just directly compiles to its own bytecode.
- First release: 2013
- engine262
- Support: 100% spec compliance
- Implementation language: JavaScript
- Runtime: AST interpreter
- Parser: Hand-written
- JerryScript
- Support: ES5
- Implementation language: C
- Runtime: Bytecode VM
- Parser: Hand-written
- First release: 2016?
- Serenity's LibJS
- Support: Progressing toward compliance
- Implementation language: C++
- Runtime: Bytecode VM
- Parser: Hand-written
- Notes: Might also work outside of Serenity but documentation on building/running it on Linux is hard to find.
- goja: JavaScript interpreter for Go
- Support: ES5
- Implementation language: Go
- Runtime: Bytecode VM
- Parser: Hand-written
- First release: 2017?
- otto: JavaScript interpreter for Go
- Support: ES5
- Implementation language: Go
- Runtime: AST interpreter
- Parser: Hand-written
- First release: 2012?
- Notes: The AST interpreter-only implementation might suggest this implementation is slower than Goja. I don't have benchmarks for that.
- Jurassic: JavaScript parser and interpreter for .NET
- Support: ES5
- Implementation language: C#
- Runtime: Compiles to .NET
- Parser: Hand-written
- First release: 2011?
- Jint
- Support: ES5, most of ES6/7/8
- Implementation language: C#
- Runtime: AST interpreter
- Parser: Hand-written via Esprima.NET
- First release: 2014?
- Notes: Thanks fowl2 for mentioning!
- NiL.JS
- Support: ES6
- Implementation language: C#
- Runtime: AST interpreter
- Parser: Hand-written
- First release: 2014?
- Neil Fraser's JS-Interpreter
- Support: ES5
- Implementation language: JavaScript
- Runtime: AST interpreter
- Parser: Hand-written, uses Acorn
- First release: 2014?
- BESEN: Bytecode VM and JIT compiler in Object Pascal
- Support: ES5
- Implementation language: Object Pascal
- Runtime: Bytecode VM with JIT for x86 and x86_64
- Parser: Hand-written
- First release: 2015?
These last few are not toys but they are also more experimental or, in AssemblyScript's case, not JavaScript.
- boa: JavaScript interpreter for Rust
- Support: Unclear
- Implementation language: Rust
- Runtime: Bytecode VM
- Parser: Hand-written
- First release: 2019?
- AssemblyScript
- Support: Subset of TypeScript
- Implementation language: AssemblyScript subset of TypeScript
- Runtime: webassembly
- Parser: Hand-written
- JavaScript in Kawa Scheme
- JavaScript in GNU Guile Scheme
- ReevaJS
- Support: ES5 (with exceptions)
- Implementation language: Kotlin
- Runtime: Stack machine
- Parser: Hand-written
Research Implementations
- Higgs
- Support: Unclear
- Implementation language: D
- Runtime: Bytecode VM and JIT compiler on x64
- Parser: Hand-written
- eJS
- Support: Unclear
- Implementation language: Java
- Runtime: Bytecode VM
- Parser: ANTLR
- Notes: eJS is a framework to generate JavaScript VMs that are specialised for applications.
- Jessie: safe subset of JavaScript non-exploitable smart contracts
- Support: some subset of ES2017
- ???
- See https://github.com/agoric-labs/jessica for more info.
- https://github.com/b9org/b9
- https://www.defensivejs.com/
Thanks to @smarr for contributing eJS, Higgs, and b9!
Notable Abandoned
- DMDScript
- Support: Unclear
- Implementation language: D
- Runtime: Bytecode VM
- Parser: Hand-written
- Notes: It's possible this is commercially maintained by DigitalMars but I'm not sure. There are also references in this repo to another C++ implementation of DMDScript that may be commercial. Thanks to @moon_chilled for mentioning!
- EchoJS
- Support: Unclear
- Implementation language: JavaScript
- Runtime: Native through LLVM
- Parser: Hand-written via Esprima
- twostroke
- Support: Unclear
- Implementation language: Ruby
- Runtime: Bytecode VM
- Parser: Hand-written
- PyPy-JS
- Support: Unclear
- Implementation language: RPython
- Runtime: RPython
- Parser: EBNF parser generator
- js.js
- Support: Unclear
- Implementation language: JavaScript
- Runtime: Too scared to look at the gigantic files in this repo.
- Parser: Ditto.
- IronJS
- Support: ES3
- Implementation language: F#
- Runtime: .NET through DLR, I think.
- Parser: Hand-written
- jispy
- Support: Unclear
- Implementation language: Python
- Runtime: AST interpreter
- Parser: Unclear
- JE: Pure-Perl JavaScript Engine
- Dave Herman's JavaScript for PLT Scheme
Notable toy implementations
Great for inspiriration if you've never implemented a language before.
- js-to-c: A JavaScript to C compiler, written in C
- mjs: AST interpreter for not just ES5 or even ES3 but also ES1
- gojis: AST interpreter in Go
- tojs: Bytecode VM in Rust
- v2: Bytecode VM in Go
- SparrowJS: AST interpreter in C++
- jsc: My own experiment compiling JavaScript to C++/libV8
New post is up! Enumerating and analyzing 40+ non-V8 JavaScript implementations; of course with links to source code and parser & runtime/backend decisions.
— Phil Eaton (@phil_eaton) September 21, 2021
I hope you enjoy learning about JavaScript engines as much as I did. 😁https://t.co/dEX06WU38f pic.twitter.com/AoYScphG6m