js [options] [filename...] -- [args]
Running Node.js apps
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
ansispan modules using
npm install as
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:
3. Execute it on GraalVM using the
node command as follows:
$ 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 that GraalVM supports:
$ node --jvm --polyglot > console.log(Polyglot.eval('R', 'runif(100)')); 0.8198353068437427
We provide migration guides for code previously targeted to the Rhino or Nashorn engines. See the JavaInterop.md for an overview of supported Java interoperability features. For additional information, see the Polyglot Reference and the Embedding documentation for more information about interoperability with other programming languages.
GraalVM is ECMAScript 2018 compliant and fully compatible with a diverse range of active Node.js (npm) modules. More than 90,000 npm packages are regularly tested and compatible with GraalVM, including modules like express, react, async, request, browserify, grunt, mocha, and underscore. This release of GraalVM is based on Node.js version 10.15.2.
What version of ECMAScript do we support?
GraalVM is compatible to the ECMAScript 2018 specification. Most features of ECMAScript 2019 and some proposed features and extensions are available as well, but might not be fully implemented or compliant, yet.
How do we know it?
GraalVM is tested against the official test suite of ECMAScript, test262. Even though this test set includes some draft features, GraalVM compliance is around 95% and rising.
In our internal CI system, we test against test262, tests published by Nashorn and V8, Node unit tests, as well as GraalVM’s own unit tests.
From the graaljs code repository, you can execute the whole test262 test suite:
mx test262 gate
This will execute test262 in a mode to guarantee that local changes do not regress compatibility, i.e., results in an error if any tests expected to pass actually fail. Individual tests can be executed with
mx test262 single=built-ins/Array/length.js
Is GraalVM compatible with the original node implementation?
Node.js based on GraalVM is largely compatible with the original Node.js (based on the V8 engine). This leads to a high number of npm-based modules being compatible with GraalVM (out of the 50k modules we test, 95% of them pass all tests). Several sources of differences have to be considered.
Setup GraalVM mostly mimicks the original setup of Node, including the
npm, and similar. However, not all command-line options are supported (or behave exactly identically), you need to (re-)compile native modules against our v8.h file, etc.
Internals GraalVM is implemented on top of a JVM, and thus has a different internal architecture. This implies that some internal mechanisms behave differently and cannot exactly replicate V8 behavior. This will hardly ever affect user code, but might affect modules implemented natively, depending on V8 internals.
Performance Due to GraalVM being implemented on top of a JVM, performance characteristics vary from the original native implementation. While GraalVM’s peak performance can match V8 on many benchmarks, it will typically take longer to reach the peak (known as warmup). Be sure to give the Graal compiler some extra time when measuring (peak) performance.
GraalVM is compatible to ECMAScript 2018, guaranteeing compatibility on the language level. In addition, GraalVM uses the following approaches to check and retain compatibility to Node.js code:
- node-compat-table: GraalVM is compared against other engines using the node-compat-table module, highlighting incompatibilities that might break Node.js code.
- automated mass-testing of modules using mocha: In order to test a large set of modules, GraalVM is tested against 50k modules that use the mocha test framework. Using mocha allows automating the process of executing the test and comprehending the test result.
- manual testing of popular modules: A select list of npm modules is tested in a manual test setup. These highly-relevant modules are tested in a more sophisticated manner.
If you want your module to be tested by GraalVM in the future, ensure the module provides some mocha tests (and send us an email so we can ensure it’s on the list of tested modules).
How can one verify GraalVM works on their application?
If your module ships with tests, execute them with GraalVM.
Of course, this will only test your app, but not its dependencies.
You can use the compatibility checker to find whether the module you’re interested in is tested on GraalVM, whether the tests pass successfully and so on.
Additionally, you can upload your
package.json file into that utility and it’ll analyze all your dependencies at once.
On the command line,
--js.<property>=<value> sets options that tune language features and extensions.
The following options are currently supported:
--js.annex-b: enables ECMAScript Annex B web compatibility features. Boolean value, default is
--js.array-sort-inherited: defines whether
Array.protoype.sortshould sort inherited keys (implementation-defined behavior). Boolean value, default is
--js.atomics: enables ES2017 Atomics. Boolean value, default is
--js.ecmascript-version: emulates a specific ECMAScript version. Integer value (
9), default is the latest version.
--js.intl-402: enables ECMAScript Internationalization API. Boolean value, default is
--js.regexp-static-result: provides static
RegExpproperties containing results of the last successful match, e.g.:
RegExp.$1(legacy). Boolean value, default is
--js.shared-array-buffer: enables ES2017 SharedArrayBuffer. Boolean value, default is
--js.strict: enables strict mode for all scripts. Boolean value, default is
--js.timezone: sets the local time zone. String value, default is the system default.
--js.v8-compatibility-mode: provides better compatibility with Google’s V8 engine. Boolean value, default is
--help:languagesto see the full list of available options.
See the Polyglot Reference for information on how to set options programmatically when embedding.
--jvm executes the application on the JVM instead of the native image.
--vm.<option> passes VM options and system properties to the native image.
To pass JVM options to GraalVM you need to provide
--jvm --vm.<option>. List all available system properties to the native image,
JVM and VM options and with
System properties can be set as follows:
--vm.Dgraal.TraceTruffleCompilation=true will print finished compilations.
--compiler.<property>=<value> passes settings to the compiler.
--compiler.CompilationThreshold=<Integer> sets the minimum number of invocations or loop iterations before a function is compiled.
--polyglot enables you to interoperate with other programming languages.
--<languageID>.<property>=<value> passes options to guest languages through the Graal Polyglot SDK.
--help:languages to find out which options are available.
How to achieve the best peak performance?
Optimizing JVM-based applications is a science in itself. Here are a few tips and tricks you can follow to analyse and improve peak performance:
- When measuring, ensure you have given Graal enough time to compile all hot methods before starting to measure peak performance. A useful command line option for that is
- Compare the performance between the native image and the JVM mode if possible. Depending on the characteristics of your application, one or the other might show better peak performance.
- The Polyglot API comes with several tools and options to inspect the performance of your application:
--cputracerwill print a list of the hottest methods when the application is terminated. Use that list to figure out where most time is spent in your application. More details about the command line options for the polyglot commands can be found from the polyglot documentation.
--memtracercan help you understand the memory allocations of your application.