karate-js/README.md
A lightweight JavaScript engine implemented in Java from scratch, designed to run on the JVM with full support for concurrent thread execution.
See also: Design Principles | Design | JS Engine Reference | karate-core
Note: This module was previously maintained as a separate project at karatelabs/karate-js. It has been folded into karate but remains reusable by third-party projects. A lot of improvements and more syntax support has gone in. We have done extensive testing with code typically written by LLMs.
The JVM JavaScript landscape has a troubled history:
We need a JavaScript engine we completely control, ensuring that engine changes never impact our users. The decision to write one from scratch was not made lightly, and is explained here.
| Package | Description |
|---|---|
io.karatelabs.js | Core JavaScript engine (interpreter, runtime, built-in types) |
io.karatelabs.parser | Parsing infrastructure (lexer, parser, AST nodes) shared with karate-core |
io.karatelabs.common | Shared utilities (file, OS, string operations) |
Note: The Gherkin parser lives in
karate-core(io.karatelabs.gherkinpackage) and extends the base lexer/parser classes fromio.karatelabs.parser.
These features are on the roadmap:
async/await - Will map to Java virtual threadssetTimeout() and timer functionsimport/export) - Enable JS reuse across testsWe prioritize practical functionality over full ECMAScript compliance. These features are intentionally excluded:
SymbolBigIntclass keyword (use functions and prototypes)This keeps the engine small, fast, and maintainable. Full ES compatibility is a long-term goal if there is community interest.
import io.karatelabs.js.Engine;
Engine engine = new Engine();
Object result = engine.eval("1 + 2");
// result = 3
Map<String, Object> context = new HashMap<>();
context.put("greeting", "Hello");
Engine engine = new Engine();
engine.putAll(context);
Object result = engine.eval("greeting + ' World'");
// result = "Hello World"
This module can be used independently of karate-core. If you're integrating karate-js into your own project:
<dependency>
<groupId>io.karatelabs</groupId>
<artifactId>karate-js</artifactId>
<version>2.0.0.RC1</version>
</dependency>
Contributions that improve decoupling for third-party usage are welcome.