Run JavaScript and Node.js with GraalVM Enterprise

Oracle GraalVM Enterprise Edition includes an ECMAScript compliant JavaScript engine. It is designed to be fully standard compliant, execute applications with higher performance, and provide all the benefits from the GraalVM stack, e.g., language interoperability and common tooling. With that engine, GraalVM Enterprise can execute JavaScript and Node.js applications.

To execute plain JavaScript code run:

js [options] [filename...] -- [args]

GraalVM is adapted to run unmodified Node.js applications. Applications can import npm modules, including native ones.

To run Node.js-based applications, use the node utility in the GraalVM distribution:

node [options] [filename] [args]

To install a Node.js module, use the npm executable in the /bin folder of the GraalVM package. The npm command is equivalent to the default Node.js command and supports all Node.js APIs.

1. Install the colors and ansispan modules using npm install as follows:

npm install colors ansispan

After the modules are installed, you can use them from your application.

2. Add the following code snippet to a file named app.js and save it in the same directory where you installed Node.js modules:

  // RUN-CMD: rm -rf node_modules
// RUN-CMD: npm install ansispan colors
// RUN-CMD: node {file}
// RUN-CMD: rm -r node_modules

// BEGIN-SNIPPET

const http = require("http");
const span = require("ansispan");
require("colors");

http.createServer(function (request, response) {
    response.writeHead(200, {"Content-Type": "text/html"});
    response.end(span("Hello Graal.js!".green));
}).listen(8000, function() { console.log("Graal.js server running at http://127.0.0.1:8000/".red); });
// END-SNIPPET

setTimeout(function() { console.log("DONE!"); process.exit(); }, 2000);

  

3. Execute it on GraalVM using the node command as follows:

node app.js

Interoperability

GraalVM Enterprise provides an API for programming language interoperability between Node.js and JavaScript and any other language written with the Truffle Language Implementation framework (Python, R, Ruby).

From JavaScript code you can access Java applications, as in the following example:

node --jvm
> var BigInteger = Java.type('java.math.BigInteger');
> console.log(BigInteger.valueOf(2).pow(100).toString(16));
10000000000000000000000000

You can also call methods in other programming languages:

node --jvm --polyglot
> console.log(Polyglot.eval('R', 'runif(100)')[0]);
0.8198353068437427

See the JavaInterop.md for an overview of supported Java interoperability features. For more information about interoperability with other programming languages, see Write Polyglot Programs and Embed Languages.

JavaScript and Node.js Command Line Options

On the command line, --js.<property>=<value> sets options that tune language features and extensions. The following options are currently supported:

Basic Options of js Launcher

Option Description
-e, --eval CODE Evaluate the code.
-f, --file FILE Load a script file.
--strict Run in strict mode.
--version Print the version and exit.

Language Options

Option Description
--js.ecmascript-version Emulate a specific ECMAScript version. Integer value (5-9), default is the latest version.
--js.intl-402 Enable ECMAScript Internationalization API. Boolean value, default is false.
--js.strict Enable strict mode for all scripts. Boolean value, default is false.

GraalVM Options

Option Description
--jvm Enable Java interoperability and execute the application on the JVM.
–-vm.<option> Pass JVM options to GraalVM (e.g. --jvm.Xmx<size>). List available JVM options with --jvm.help.
–-vm.D<name>=<value> Set system properties. For example, --jvm.Dgraal.TraceTruffleCompilation=true will print finished compilations.
--native.<option> Pass VM options and system properties to a native image.
--native.help List available VM options.
--engine.Mode=default Configure the execution mode of the engine. The execution mode automatically tunes the polyglot engine towards latency or throughput. throughput - collects the maximum amount of profiling information and compile using the maximum number of optimizations. This mode results in slower application startup but better throughput. This mode uses the compiler configuration community or enterprise if not specified otherwise. default - uses a balanced engine configuration. This mode uses the compiler configuration community or enterprise if not specified otherwise. latency - collects only minimal profiling information and compile as fast as possible with less optimal generated code. This mode results in faster application startup but less optimal throughput. This mode uses the compiler configuration economy if not specified otherwise.
--engine.CompilerConfiguration=name Select the GraalVM compiler configuration to use for polyglot application code. If omitted, the compiler configuration with the highest auto-selection priority is used. To see the set of available configurations, supply the value help to this option. The current configurations and their semantics are: enterprise - produces highly optimized code with a possible trade-off to compilation time. This value is only available in GraalVM Enterprise. community - produces reasonably optimized code with a faster compilation time. economy - compiles as fast as possible with less optimal throughput of the generated code.
--engine.TraceCompilation=false Print an informational line to the console for each completed compilation.
--experimental-options Unlock experimental features that are behind flags. For example, to diagnose the memory allocations of a JavaScript application with --memtracer profiling tool, run js --experimental-options --memtracer program.js. The option is experimental.

Polyglot Options

Option Description
--polyglot Enable interoperability with other GraalVM languages.
--<languageID>.<property>=<value> Passes options to guest languages through the GraalVM Polyglot SDK.

The --<languageID>.<property>=<value> syntax is to allow any language launcher to access the options of other GraalVM supported languages.

GraalVM JavaScript Compatibility

GraalVM is ECMAScript 2020 compliant and fully compatible with a diverse range of active Node.js (npm) modules. More than 100,000 npm packages are regularly tested and are compatible with GraalVM, including modules like express, react, async, request, browserify, grunt, mocha, and underscore. The latest release of GraalVM is based on Node.js version 12.15.0.

The compatibility of GraalVM JavaScript is verified by external sources, like the Kangax ECMAScript compatibility table.

GraalVM JavaScript is tested against a set of test engines, like the official test suite of ECMAScript, test262, as well as tests published by V8 and Nashorn, Node.js unit tests, and GraalVM’s own unit tests.

For a reference of the JavaScript APIs that GraalVM Enterprise supports, see GRAAL.JS-API.

Nashorn Compatibility Mode

GraalVM JavaScript provides a Nashorn compatibility mode for some of the functionality not exposed by default, but necessary to run an application that was built for Nashorn specifically. Check the list of extensions to JavaScript (ECMAScript) that are available in GraalVM JavaScript. Some of them provide features that are available in Nashorn as well. For ECMAScript compatibility, most of those features are deactivated by default in GraalVM but can be activated with flags. Note that using the Nashorn compatibility mode allows your application to bypass the GraalVM security model.

If the source code includes some Nashorn-specific extensions, the Nashorn compatibility mode should be enabled. It can be activated:

  1. with the js.nashorn-compat option from the command line:
    js --experimental-options --js.nashorn-compat=true
    
  2. by using the Polyglot API:
    import org.graalvm.polyglot.Context;
    try (Context context = Context.newBuilder().allowExperimentalOptions(true).option("js.nashorn-compat", "true").build()) {
      context.eval("js", "print(__LINE__)");
    }
    
  3. by using a system property when starting a Java application:
    java -Dpolyglot.js.nashorn-compat=true MyApplication
    

It is recommended to use the Nashorn compatibility mode only as a means of getting your application running on GraalVM JavaScript initially. Enabling the Nashorn compatibility mode gives your application full access to the Java mode. This bypasses the GraalVM security model of limiting JavaScript user code to “less trusted code” that is consistent with all other GraalVM languages. It is highly recommended not to use the Nashorn compatibility mode in production code if you execute less trusted user code. Some features of the Nashorn compatibility mode might in the future conflict with new ECMAScript and/or GraalVM JavaScript features.

Find migration guides for code previously targeted to the Nashorn or Rhino engines.