Kotlin/WASM: Compiling to WebAssembly for the Browser
Target Kotlin/WASM, integrate with JavaScript, and run in a browser environment.
Kotlin/WASM: Compiling to WebAssembly for the Browser is a free Kotlin Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Kotlin Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is Kotlin/WASM?
Kotlin/WASM is a Kotlin compilation target that produces WebAssembly (.wasm) modules for execution in browsers and server-side WASM runtimes. It is separate from Kotlin/JS and provides better performance and a smaller binary size for compute-intensive code.
Current Status (Kotlin 2.0)
As of Kotlin 2.0, Kotlin/WASM targets the WasmGC proposal — a W3C standard that brings garbage-collected objects natively to WebAssembly. WasmGC is supported in Chrome 119+, Firefox 120+, and Safari 18+. Kotlin/WASM is Stable as of Kotlin 2.1.
Setting Up a Kotlin/WASM Target
In your KMP build.gradle.kts, declare the WASM target and an executable binary:
kotlin {
wasmJs {
browser()
binaries.executable()
}
sourceSets {
val wasmJsMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-browser:0.3")
}
}
}
}Writing Kotlin Code for WASM
Kotlin/WASM code looks like regular Kotlin. You can share logic with other KMP targets via commonMain. Browser DOM access is via the kotlinx-browser library:
import kotlinx.browser.document
import kotlinx.browser.window
fun main() {
val p = document.createElement("p")
p.textContent = "Hello from Kotlin/WASM!"
document.body!!.appendChild(p)
}Building and Running
Run ./gradlew wasmJsBrowserDevelopmentRun to start a dev server with live reload. For a production build: ./gradlew wasmJsBrowserDistribution. Output is in build/dist/wasmJs/productionExecutable/.
JavaScript Interop in Kotlin/WASM
Use @JsExport to expose Kotlin functions to JavaScript. Use external declarations to call JavaScript APIs from Kotlin:
external fun console_log(msg: String): Unit
@JsExport
fun add(a: Int, b: Int): Int = a + bKotlin/WASM vs Kotlin/JS
Kotlin/JS: transpiles to JavaScript — full JS ecosystem access, mature tooling, runs everywhere JS runs. Kotlin/WASM: compiles to WebAssembly — faster execution for computation-heavy code, type-safe memory model, requires WasmGC browser support. Use Kotlin/JS for general web apps; consider Kotlin/WASM for performance-critical modules.
Compose for Web (WASM)
JetBrains' Compose Multiplatform targets Kotlin/WASM for building web UIs with the same Compose APIs used on Android and Desktop. The entire UI renders to a Canvas element via WASM:
// build.gradle.kts with Compose Multiplatform
plugins { id("org.jetbrains.compose") }
// In wasmJsMain
@OptIn(ExperimentalComposeUiApi::class)
fun main() = CanvasBasedWindow("MyApp") {
Text("Hello, Compose WASM!")
}Binary Size and Optimization
WASM binaries are optimized with wasm-opt during production builds. Tree-shaking removes unused Kotlin standard library code. Typical Kotlin/WASM hello-world is 200–400 KB gzipped. Enable binaryenArgs = listOf("-O3") for maximum optimization.
Sharing Code with the JVM and Native
Because Kotlin/WASM is a KMP target, domain logic, algorithms, and data models in commonMain are shared automatically. Platform-specific code (DOM manipulation, file I/O) lives in wasmJsMain using actual declarations.
Limitations and Roadmap
Current limitations: no direct access to NPM packages (use JS interop), limited debugger support compared to Kotlin/JS, WasmGC browser support required (not available in older browsers). The Kotlin team is actively improving tooling, performance, and standard library coverage for WASM.
Quick Check
What WebAssembly proposal does Kotlin/WASM (Kotlin 2.0+) target, enabling garbage-collected objects natively in WASM?
Recap: Kotlin/WASM
Key takeaways:
- Kotlin/WASM compiles to WebAssembly via the WasmGC proposal (Stable in Kotlin 2.1)
- Declare
wasmJs { browser(); binaries.executable() }in KMP Gradle config - DOM access via
kotlinx-browser; JS interop viaexternaland@JsExport - Build with
wasmJsBrowserDistribution; dev server withwasmJsBrowserDevelopmentRun - Share domain logic in
commonMain; platform specifics inwasmJsMain
Frequently asked questions
Is the “Kotlin/WASM: Compiling to WebAssembly for the Browser” lesson free?
Yes — the full text of “Kotlin/WASM: Compiling to WebAssembly for the Browser” is free to read here on the web, and the Kotlin Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Kotlin Academy course, upgrade to CoddyKit PRO.
What will I learn in “Kotlin/WASM: Compiling to WebAssembly for the Browser”?
Target Kotlin/WASM, integrate with JavaScript, and run in a browser environment. You practise Kotlin Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Kotlin Academy?
No prior experience is required. Kotlin Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Kotlin/WASM: Compiling to WebAssembly for the Browser” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Kotlin Academy lesson?
Yes. Every Kotlin Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Kotlin/Native Overview: Targets, Toolchain & Compilation
- Memory Management in Kotlin/Native: The New MM
- C Interop with cinterop and .def Files
- Kotlin/WASM: Compiling to WebAssembly for the Browser