Kotlin on Web
Playground / How it works

How it works

Kotlin 2.5.0-dev-9169 · Oracle GraalVM 25.4 · Last modified: October 18, 2026

The playground compiles and runs Kotlin without any server. Your code never leaves the browser tab: the real Kotlin compiler (K2) and the Kotlin Analysis API are downloaded once as WebAssembly modules and run inside Web Workers.

Both modules are the official JVM jars, translated ahead of time to WebAssembly by GraalVM Web Image (native-image --tool:svm-wasm). Nothing is rewritten from the compiler sources.

What the server doesGitHub Pages only serves static files: index.html, two .wasm modules (about 70 MB each) and the standard library (12 MB). Compilation, execution and analysis all happen on your machine.

Two layers of WebAssembly

The word WebAssembly appears twice in this project, for two different reasons:

LayerMade byWhenWhat it is
The compilerGraalVM Web ImageOnce, at build timekotlin-compiler.jar translated to .wasm
Your programKotlin/Wasm backendEvery time you press RunYour source compiled to main.wasm

In other words, a compiler that is WebAssembly produces a program that is also WebAssembly.

Web Image is a translator, not a JVMGraalVM is only needed on the build machine. It analyzes the jar ahead of time (AOT) and emits WasmGC code, so the browser runs the compiler with no JVM at all. Garbage collection is done by the browser itself.

Building the compiler

This happens once, on a developer machine. Click an arrow or use the buttons to walk through the steps.

Running your code

This happens every time you press Run. Only the first run downloads the compiler; later runs take about two seconds.

Autocomplete and diagnostics

A second module, built the same way from the Kotlin Analysis API (the engine IntelliJ IDEA uses), runs in its own worker. The editor asks it two kinds of questions:

  • analyze(source): 300 ms after you stop typing. The answer becomes the red and yellow underlines.
  • complete(source, offset): when you type . or press Ctrl+Space. The answer becomes the suggestion list.
// worker message → answer (JSON)
{ "operation": "complete", "text": source, "argument": "46" }
→ { "from": 46, "items": [{ "label": "length", "kind": "property", "detail": "Int" }, ...] }

Each request builds a fresh analysis session over one source file that depends on the standard library klib, then disposes it. On small files a request takes about 150 to 700 ms.

Building on Windows

The original project was built on Linux. Building the same images on Windows needed five fixes:

ProblemFix
GraalVM 25.0 (LTS) ignores --tool:svm-wasmUse the 25.4 innovation release (25i4)
Native Image compiles small C query files even for WasmInstall Visual Studio Build Tools (C++), so cl.exe exists
@Delete methods should have a single calleeThe Windows JDK registers SunMSCAPI (crypt32/ncrypt). Build with a java.security that leaves it out
The command line is too longPass the Analysis API classpath through a @argfile
Scenario checks fail at wrong offsetsGit checked the sample out with CRLF line endings; convert it to LF
native-image --tool:svm-wasm \
  -J-Djava.security.properties==no-mscapi.security \
  -J-Xmx24g -Os -H:ImageHeapObjectsPerFunction=20000 \
  -cp <patched jars> editor.compilerhost.web.WebMain

Limitations

  • First visit downloads about 160 MB (cached afterwards).
  • One file and the standard library only. No other libraries yet.
  • No threads: programs run single-threaded and are stopped after 10 seconds.
  • Completion after . does not offer extension functions such as uppercase().
  • GraalVM Web Image is still experimental.

Credits

The compiler and analysis hosts, the bytecode patches and the worker protocol come from alex28sh/wasm-code-editor. Built with GraalVM Web Image and Binaryen. The editor is CodeMirror 5, like the official Kotlin Playground.