graaljs
A high-performance, ECMAScript compliant, and embeddable JavaScript runtime for Java
Top Related Projects
GraalVM CE binaires built by the GraalVM community
Node.js JavaScript runtime ✨🐢🚀✨
A modern runtime for JavaScript and TypeScript.
Ultra-lightweight JavaScript engine for the Internet of Things.
The official mirror of the V8 Git repository
ChakraCore is an open source Javascript engine with a C API.
Quick Overview
GraalJS is an implementation of JavaScript on top of GraalVM, a high-performance runtime for multiple programming languages. It aims to fully implement the ECMAScript 2023 specification, providing a fast and compliant JavaScript engine that can be embedded in Java applications or run standalone.
Pros
- High performance due to GraalVM's advanced optimizations
- Seamless interoperability with Java and other GraalVM languages
- Full ECMAScript 2023 compliance
- Ability to run JavaScript both embedded in Java applications and standalone
Cons
- Larger footprint compared to some other JavaScript engines
- Potential learning curve for developers unfamiliar with GraalVM ecosystem
- May require more setup and configuration compared to traditional JavaScript runtimes
- Limited community support compared to more established JavaScript engines
Code Examples
- Running JavaScript code from Java:
import org.graalvm.polyglot.*;
public class GraalJSExample {
public static void main(String[] args) {
Context context = Context.create("js");
Value result = context.eval("js", "2 + 3");
System.out.println(result.asInt()); // Outputs: 5
}
}
- Accessing Java objects from JavaScript:
import org.graalvm.polyglot.*;
public class JavaInteropExample {
public static void main(String[] args) {
Context context = Context.create("js");
context.getBindings("js").putMember("javaObject", new MyJavaClass());
context.eval("js", "javaObject.sayHello('GraalJS')");
}
}
class MyJavaClass {
public void sayHello(String name) {
System.out.println("Hello, " + name + "!");
}
}
- Using JavaScript modules:
// math.js
export function add(a, b) {
return a + b;
}
// main.js
import { add } from './math.js';
console.log(add(2, 3)); // Outputs: 5
Getting Started
To get started with GraalJS:
- Install GraalVM (https://www.graalvm.org/downloads/)
- Set JAVA_HOME to point to your GraalVM installation
- Add GraalJS dependency to your project (if using Maven):
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>22.3.0</version>
</dependency>
- Create a new Java file with the following code:
import org.graalvm.polyglot.*;
public class GraalJSHelloWorld {
public static void main(String[] args) {
Context context = Context.create("js");
context.eval("js", "console.log('Hello, GraalJS!')");
}
}
- Compile and run the Java file to see "Hello, GraalJS!" printed to the console.
Competitor Comparisons
GraalVM CE binaires built by the GraalVM community
Pros of graalvm-ce-builds
- Provides a complete GraalVM distribution, including multiple language runtimes
- Offers pre-built binaries for easier installation and deployment
- Includes additional tools like Native Image for ahead-of-time compilation
Cons of graalvm-ce-builds
- Larger download size due to the inclusion of multiple components
- May include unnecessary components for users only interested in JavaScript
- Potentially more complex configuration for specific use cases
Code Comparison
graaljs:
const Context = Polyglot.import('org.graalvm.polyglot.Context');
const context = Context.create('js');
context.eval('js', 'console.log("Hello from GraalJS!");');
graalvm-ce-builds:
import org.graalvm.polyglot.*;
Context context = Context.create();
Value result = context.eval("js", "console.log('Hello from GraalVM!');");
The code examples demonstrate how to create a JavaScript context and execute code. graaljs focuses on JavaScript-specific usage, while graalvm-ce-builds showcases the polyglot capabilities of GraalVM.
Node.js JavaScript runtime ✨🐢🚀✨
Pros of Node.js
- Larger ecosystem with more packages and community support
- Better performance for I/O-intensive operations
- Wider adoption and more mature tooling
Cons of Node.js
- Single-threaded nature can limit CPU-intensive tasks
- Lack of native support for polyglot programming
- Less suitable for enterprise Java environments
Code Comparison
Node.js:
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n');
});
server.listen(3000);
GraalJS:
var http = Java.type('com.sun.net.httpserver.HttpServer');
var InetSocketAddress = Java.type('java.net.InetSocketAddress');
var server = http.create(new InetSocketAddress(3000), 0);
server.createContext("/", function(exchange) {
exchange.sendResponseHeaders(200, 0);
exchange.getResponseBody().write("Hello World\n".getBytes());
exchange.close();
});
server.start();
The Node.js example demonstrates its simplicity and native JavaScript approach, while the GraalJS example showcases its ability to interact with Java classes directly within JavaScript code.
A modern runtime for JavaScript and TypeScript.
Pros of Deno
- Built-in TypeScript support without additional configuration
- Secure by default, with explicit permissions for file, network, and environment access
- Includes a standard library and built-in testing framework
Cons of Deno
- Smaller ecosystem compared to Node.js, which GraalJS can leverage
- Limited compatibility with existing Node.js modules
- Steeper learning curve for developers familiar with traditional Node.js environments
Code Comparison
Deno:
import { serve } from "https://deno.land/std@0.140.0/http/server.ts";
serve(() => new Response("Hello, World!"));
GraalJS:
const http = require('http');
http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello, World!');
}).listen(8080);
Key Differences
- Deno uses ES modules and URL imports, while GraalJS follows Node.js CommonJS-style imports
- Deno's standard library is more comprehensive and modern compared to GraalJS
- GraalJS focuses on Java interoperability, while Deno emphasizes web standards and security
Use Cases
- Deno: Modern web applications, serverless functions, and TypeScript-heavy projects
- GraalJS: Java applications requiring JavaScript integration, polyglot environments
Ultra-lightweight JavaScript engine for the Internet of Things.
Pros of JerryScript
- Lightweight and optimized for resource-constrained devices
- Highly portable with minimal dependencies
- Supports a wide range of embedded platforms
Cons of JerryScript
- Limited ECMAScript support (ES5.1 with some ES2015 features)
- Smaller community and ecosystem compared to GraalJS
- Less integration with existing Java/JVM ecosystems
Code Comparison
JerryScript:
#include "jerryscript.h"
int main (void)
{
const jerry_char_t script[] = "print('Hello, World!');";
jerry_run_simple(script, sizeof(script) - 1, JERRY_INIT_EMPTY);
return 0;
}
GraalJS:
import org.graalvm.polyglot.*;
public class HelloWorld {
public static void main(String[] args) {
Context context = Context.create("js");
context.eval("js", "console.log('Hello, World!');");
}
}
JerryScript focuses on C-based embedded systems, while GraalJS integrates with Java and the JVM ecosystem. JerryScript is more suitable for resource-constrained environments, whereas GraalJS offers broader language support and integration capabilities.
The official mirror of the V8 Git repository
Pros of v8
- Widely adopted and battle-tested in major browsers and Node.js
- Highly optimized for performance with advanced JIT compilation
- Extensive documentation and community support
Cons of v8
- Larger codebase and more complex architecture
- Limited language interoperability compared to GraalJS
- Primarily focused on JavaScript, with less emphasis on polyglot capabilities
Code Comparison
v8:
Local<Context> context = Context::New(isolate);
Context::Scope context_scope(context);
Local<String> source = String::NewFromUtf8(isolate, "'Hello' + ', World!'");
Local<Script> script = Script::Compile(context, source).ToLocalChecked();
Local<Value> result = script->Run(context).ToLocalChecked();
GraalJS:
Context context = Context.create("js");
Value result = context.eval("js", "'Hello' + ', World!'");
System.out.println(result.asString());
context.close();
The v8 example demonstrates C++ API usage, while GraalJS showcases Java integration. GraalJS offers a simpler API for polyglot execution, whereas v8 provides lower-level control and is more tightly integrated with C++.
ChakraCore is an open source Javascript engine with a C API.
Pros of ChakraCore
- Mature and battle-tested engine, used in Microsoft Edge and other applications
- Strong performance, especially in JIT compilation scenarios
- Extensive support for modern ECMAScript features
Cons of ChakraCore
- Less active development and community support in recent years
- Limited cross-platform support compared to GraalJS
- Larger memory footprint for small applications
Code Comparison
ChakraCore:
const Context = require('chakra-core').Context;
const ctx = new Context();
const result = ctx.eval('2 + 2');
console.log(result); // Output: 4
GraalJS:
const Context = require('graaljs').Context;
const ctx = Context.create();
const result = ctx.eval('js', '2 + 2');
console.log(result); // Output: 4
Both engines provide similar APIs for creating contexts and evaluating JavaScript code. However, GraalJS requires specifying the language ('js') when evaluating code, while ChakraCore assumes JavaScript by default.
ChakraCore offers a more traditional JavaScript engine experience, while GraalJS provides tighter integration with the Java ecosystem and polyglot capabilities. The choice between the two depends on specific project requirements, such as performance needs, platform support, and integration with other languages or runtimes.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
GraalJS
GraalJS is a JavaScript engine implemented in Java on top of GraalVM. It is an ECMAScript-compliant runtime to execute JavaScript and Node.js applications, and includes all the benefits from the GraalVM stack including interoperability with Java. GraalJS is an open-source project.
The goals of GraalJS are:
- Full compatibility with the latest ECMAScript specification
- Interoperability with Java
- Interoperability with WebAssembly using the JavaScript WebAssembly API
- Running JavaScript with the best possible performance
- Support for Node.js applications, including native packages
- Simple upgrading from applications based on Nashorn or Rhino
- Embeddability in systems like Oracle RDBMS or MySQL
Getting Started
As of version 23.1.0, GraalJS is available as Maven artifacts. We also provide standalone distributions of the JavaScript and Node.js runtimes.
Maven Artifacts
Thanks to GraalJS, you can easily embed JavaScript into a Java application. All necessary artifacts can be downloaded directly from Maven Central.
All artifacts relevant to embedders can be found in the Maven dependency group org.graalvm.polyglot.
Below is a minimal Maven dependency setup that you can copy into your pom.xml:
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>polyglot</artifactId>
<version>${graaljs.version}</version>
</dependency>
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>js</artifactId>
<version>${graaljs.version}</version>
<type>pom</type>
</dependency>
This enables GraalJS which is built on top of Oracle GraalVM and licensed under the GraalVM Free Terms and Conditions (GFTC).
Use js-community
if you want to use GraalJS built on GraalVM Community Edition.
To access polyglot isolate artifacts (GFTC only), use the -isolate
suffix instead (e.g. js-isolate
).
See the polyglot embedding demonstration on GitHub for a complete runnable example.
You can use GraalJS with GraalVM JDK, Oracle JDK, or OpenJDK. If you prefer running on a stock JVM, have a look at Run GraalJS on a Stock JDK. Note that in this mode many features and optimizations of GraalVM are not available. Due to those limitations, running on a stock JVM is not a supported feature - please use a GraalVM instead.
Standalone Distributions
Standalone distributions are published on GitHub. There are two language runtime options to choose from:
- Native launcher compiled ahead of time with GraalVM Native Image;
- JVM-based runtime.
To distinguish between them, a standalone that comes with a JVM has a -jvm
infix in the name.
Also, the GraalVM Community Edition version has -community
in the name, for example, graaljs-community-<version>-<os>-<arch>.tar.gz
.
Four different configurations are available for each component and platform combination:
Runtime | License | Archive Infix |
---|---|---|
Native | GFTC | none |
JVM | GFTC | -jvm |
Native | UPL | -community |
JVM | UPL | -community-jvm |
To install GraalJS from a standalone, download and extract the archive from the GitHub Releases page.
After the installation, the js
or node
executable in the bin
subdirectory can be used to run JavaScript files or Node modules, respectively.
If no file is provided on the command line, an interactive shell (REPL) will be spawned.
Note: If you are using macOS, first remove the quarantine attribute from the archive:
shell sudo xattr -r -d com.apple.quarantine <archive>.tar.gz
Node.js Runtime
GraalJS can run unmodified Node.js applications. GraalVM's Node.js runtime is based on a recent version of Node.js, and runs the GraalJS engine instead of Google V8. It provides high compatibility with the existing NPM packages. This includes NPM packages with native implementations. Note that some NPM modules may require to be recompiled from source with GraalJS (if they ship with binaries that have been compiled for Node.js based on V8).
Node.js is available as a separate standalone distribution. See how to get started with Node.js.
Documentation
Extensive user documentation is available on the website. In addition, there is documentation in this repository under docs, for users and contributors. For contributing, see also a guide on how to build GraalJS from source code.
Compatibility
GraalJS is compatible with the ECMAScript 2024 specification. New features, new ECMAScript proposals, scheduled to land in future editions, are added frequently and are accessible behind an option. See the CHANGELOG.md for the proposals already adopted.
In addition, some popular extensions of other engines are supported. See GraalJS Compatibility.
Operating Systems Compatibility
The core JavaScript engine is a Java application and is thus compatible with every operating system that provides a compatible JVM. See Run GraalJS on a Stock JDK. We provide binary distributions and fully support GraalJS on Linux (x64, AArch64), macOS (x64, AArch64), and Windows (x64), currently.
Stay Connected with the Community
See graalvm.org/community for how to stay connected with the development community. The channel graaljs on graalvm.slack.com is a good way to get in touch with the team behind GraalJS. Report any GraalJS-specific issues at the oracle/graaljs GitHub repository.
License
GraalJS source code and community distributions are available under the Universal Permissive License (UPL), Version 1.0.
Non-community artifacts are provided under the GraalVM Free Terms and Conditions (GFTC) including License for Early Adopter Versions.
Top Related Projects
GraalVM CE binaires built by the GraalVM community
Node.js JavaScript runtime ✨🐢🚀✨
A modern runtime for JavaScript and TypeScript.
Ultra-lightweight JavaScript engine for the Internet of Things.
The official mirror of the V8 Git repository
ChakraCore is an open source Javascript engine with a C API.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot