CheerpJ 5 adds Java 21 and Java 25, and ships the full JDK, including javac. Here's how to use both.

Running a JAR on Java 25

<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <script src="https://cjrtnc.leaningtech.com/5.0/loader.js"></script> </head> <body> <script type="module"> await cheerpjInit({ version: 25 }); cheerpjCreateDisplay(800, 600); await cheerpjRunJar("/app/my_application.jar"); </script> </body> </html> 

version defaults to 8. The supported values are 8, 11, 17, 21 and 25. /app/ is your web server's root, so serve the folder over HTTP (npx http-server -p 8080). Opening the file from disk won't work.

To run a main class with dependencies, use cheerpjRunMain, with the class path separated by ::

await cheerpjRunMain("com.example.Main", "/app/app.jar:/app/lib.jar"); 

Compiling in the browser

CheerpJ's virtual filesystem has three mount points:

  • /app/: your web server, read-only
  • /files/: IndexedDB, read-write from Java
  • /str/: written from JavaScript, read-only from Java

Write the source to /str/, compile it into /files/, then run it:

await cheerpjInit({ version: 25 }); cheerpOSAddStringFile("/str/Hello.java", ` public class Hello { sealed interface Shape permits Circle, Square {} record Circle(double r) implements Shape {} record Square(double side) implements Shape {} static double area(Shape s) { return switch (s) { case Circle c -> Math.PI * c.r() * c.r(); case Square q -> q.side() * q.side(); }; } public static void main(String[] args) { System.out.println(area(new Circle(1))); System.out.println(area(new Square(2))); } } `); const rc = await cheerpjRunMain( "com.sun.tools.javac.Main", "", "-d", "/files/out", "/str/Hello.java" ); if (rc === 0) { await cheerpjRunMain("Hello", "/files/out"); } 

cheerpjRunMain resolves with the exit code, so a non-zero rc means compilation failed. Sealed interfaces and pattern matching in switch need Java 21 or later, so this fails on version: 17.

Switching on WasmGC

CheerpJ normally compiles bytecode to JavaScript. CheerpJ 5 has an experimental backend that generates WebAssembly using WasmGC:

await cheerpjInit({ version: 25, wasmGC: true }); 

It needs Chrome or Edge 137+, Firefox 153+ or Safari 27+. Most applications won't run on it yet.

Docs: cheerpj.com/docs

The javac call isn't covered in the docs, so it needs testing before you post this.