- GraalVM 25 (Latest)
- GraalVM for JDK 21
- GraalVM for JDK 17
- Archives
- Dev Build
Getting Started with Web Image
Web Image takes a JVM application, performs ahead-of-time (AOT) compilation using GraalVM Native Image, and produces a WebAssembly module together with a JavaScript runtime wrapper that can run in browsers or Node.js environments.
Web Image uses the standard GraalVM Native Image toolchain and is enabled by passing the --tool:svm-wasm option to the native-image tool.
Note: Web Image is an experimental technology and under active development. APIs, tooling, and capabilities may change.
Prerequisites
To build Web Image applications, you need:
- An Early Access build of Oracle GraalVM 25 (25e1) or later.
- All prerequisites required for Native Image building.
- Binaryen toolchain version 119 or later, available on the system path. Web Image uses
wasm-asfrombinaryenas its assembler.- macOS: It is recommended to install Binaryen using Homebrew, as the pre-built binaries from GitHub may be quarantined by the operating system:
brew install binaryen - Other platforms: Download a pre-built release for your platform from GitHub.
- macOS: It is recommended to install Binaryen using Homebrew, as the pre-built binaries from GitHub may be quarantined by the operating system:
Advantages
Web Image opens new use-cases for JVM ecosystem such as:
- Running JVM applications in browsers or on Wasm-enabled runtimes such as Node.js
- Producing portable artifacts that can run across multiple environments
Current Status and Limitations
Web Image in GraalVM is early and experimental.
It is not yet part of the native-image tool in stable releases.
You need to run on Early Access build of Oracle GraalVM 25e1 or later.
The WebAssembly code generated by Web Image makes use of various WebAssembly features from WebAssembly 3.0:
Support for WebAssembly 2.0 is generally assumed. At present, Web Image is best suited for application-style builds hosted by a JavaScript runtime.
Usage
-
Create a simple Java application. Save the following code to HelloWasm.java:
public class HelloWasm { public static int add(int a, int b) { return a + b; } public static void main(String[] args) { System.out.println(add(3, 4)); } } -
Compile the Java source file:
javac HelloWasm.java -
Build an image. Use the
native-imagetool with the Web Image backend:native-image --tool:svm-wasm HelloWasmThe
--tool:svm-wasmoption should be the first argument. If any options specific to the Wasm backend are used, they can only be added after this option.
The build produces the following artifacts in your working directory:
- hellowasm.js: a JavaScript launcher and runtime entry point;
- hellowasm.js.wasm: the compiled WebAssembly module containing Java code and runtime support (object layout, parts of Substrate VM adapted for Wasm). It is not a standalone executable.
- hellowasm.js.wat debug artifacts to understand how Java code and runtime components are lowered to WebAssembly.
Running the Application
Option 1: Run with Node.js
You cannot run .wasm directly in Wasm runtimes because the generated module depends on JavaScript-provided imports and runtime.
Thus commands such as wasmtime hellowasm.js.wasm will not work.
Run the generated JavaScript wrapper with Node.js instead:
node --experimental-wasm-exnref hellowasm.js
You should see 7 as an output.
That is main(String[]) executing, with System.out wired through JS.
The
--experimental-wasm-exnrefoption is required for Node.js versions prior to 25 to enable WebAssembly exception handling used by GraalVM.
Option 2: Run in a browser
You can also run the application in a browser using a simple HTTP server.
Browsers restrict loading Wasm modules from the local filesystem, so opening via file:// will not work.
- Create an index.html file in the working directory:
<!DOCTYPE html> <html> <body> <script src="hellowasm.js"></script> <div>Hello, GraalVM Web Image!</div> </body> </html>Instead of just loading the script, you can attach some logic after the runtime is ready.
- Start a local server using your Java or Python environment:
jwebserver -p 8000python3 -m http.server 8000 - Navigate to http://localhost:8000. When you open the page you will see the following in the browser console:
Result of add(3, 4): 7
Related Documentation
- GraalVM Web Image API
- To learn more, see how to compile javac into a Wasm module.
- Review a demo showing builds of JVM applications (such as Spring Shell) running in JavaScript-hosted Wasm environments.