web-image/docs/get-started.md
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.
To build Web Image applications, you need:
wasm-as from binaryen as its assembler.
brew install binaryen
Web Image opens new use-cases for JVM ecosystem such as:
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.
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-image tool with the Web Image backend:
native-image --tool:svm-wasm HelloWasm
The --tool:svm-wasm option 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:
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 in the current version.
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 from 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 8000
python3 -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