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
A high performance implementation of the JavaScript programming language. Built on the GraalVM by Oracle Labs.
The goals of GraalVM JavaScript are:
- Execute JavaScript code with best possible performance
- Full compatibility with the latest ECMAScript specification
- Support Node.js applications, including native packages (check)
- Allow simple upgrading from Nashorn or Rhino based applications
- Fast interoperability with Java, Scala, or Kotlin, or with other GraalVM languages like Ruby, Python, or R
- Be embeddable in systems like Oracle RDBMS or MySQL
Getting Started
The preferred way to run GraalVM JavaScript (a.k.a. GraalJS) is from a GraalVM. As of GraalVM for JDK 21, (23.1), GraalVM JavaScript and Node.js runtimes are available as standalone distributions and Maven artifacts (but no longer as GraalVM components). See the documentation on the GraalVM website for more information on how to set up GraalVM JavaScript.
Standalone Distribution
To install GraalVM JavaScript using the [standalone distribution], simply download and extract the desired archive from the GitHub Releases page.
The standalone archives for the JavaScript and Node.js distributions are named graaljs[-community][-jvm]-<version>-<os>-<arch>.tar.gz
and graalnodejs[-community][-jvm]-<version>-<os>-<arch>.tar.gz
, respectively.
Four different available 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 |
After 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.
Maven Artifact
All required artifacts for embedding GraalVM JavaScript can be found in the Maven dependency group org.graalvm.polyglot
.
Here is a minimal Maven dependency setup that you can copy into your pom.xml
:
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>polyglot</artifactId>
<version>23.1.0</version>
</dependency>
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>js</artifactId>
<version>23.1.0</version>
<type>pom</type>
</dependency>
<!-- add additional languages and tools, if needed -->
See the polyglot embedding demonstration on GitHub for a complete runnable example.
Language and tool dependencies use the GraalVM Free Terms and Conditions (GFTC) license by default.
To use community-licensed versions instead, add the -community
suffix to each language and tool dependency, e.g.:
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>js-community</artifactId>
<version>23.1.0</version>
<type>pom</type>
</dependency>
To access polyglot isolate artifacts (GFTC only), use the -isolate
suffix instead (e.g. js-isolate
).
If you prefer running it on a stock JVM, please have a look at the documentation in RunOnJDK.md
.
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.
Documentation
Extensive documentation is available on graalvm.org: see Getting Started and the more extensive JavaScript and Node.js Reference Manual.
In addition, there is documentation in the source code repository in the docs
directory, for users and contributors.
For contributors, a guide how to build GraalVM JavaScript from source code can be found in Building.md
.
Current Status
GraalVM JavaScript is compatible with the ECMAScript 2023 specification.
New features, e.g. ECMAScript proposals
scheduled to land in future editions, are added frequently and are accessible behind a flag.
See the CHANGELOG.md for the proposals already adopted.
In addition, some popular extensions of other engines are supported, see JavaScriptCompatibility.md
.
Node.js support
GraalVM JavaScript can execute Node.js applications. It provides high compatibility with existing npm packages, with high likelihood that your application will run out of the box. This includes npm packages with native implementations. Note that some npm modules will require to be re-compiled from source with GraalVM JavaScript if they ship with binaries that have been compiled for Node.js based on V8. Node.js is a separate standalone distribution.
Compatibility on Operating Systems
The core JavaScript engine is a Java application and is thus in principle compatible with every operating system that provides a compatible JVM, see RunOnJDK.md
.
We provide binary distributions and fully support GraalVM JavaScript on Linux (AMD64, AArch64), MacOS (AMD64, AArch64), and Windows (AMD64), currently.
GraalVM JavaScript Reference Manual
A reference manual for GraalVM JavaScript is available on the GraalVM website.
Stay connected with the community
See graalvm.org/community on how to stay connected with the development community.
The channel graaljs on graalvm.slack.com is a good way to get in touch with us.
Please report JavaScript-specific issues on the oracle/graaljs
GitHub repository.
License
GraalVM JavaScript source code and community distributions are available under the following license:
Non-community artifacts are provided under the following license:
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