# How to run Kotlin code in a sandbox Install a JDK and the official Kotlin compiler in an isolated microVM, compile the `.kt` file to a jar, and run it with `java -jar`. **On Runtime, a Kotlin toolchain is two installs in a sandbox you fully control, or zero in an image you build once.** Every sandbox is a Firecracker microVM with its own kernel, `sudo`, `curl` and `unzip`, so the compiler's official zip works as its documentation describes. A 2 vCPU, 4 GiB sandbox costs $0.08 an hour with both CPUs compiling and $0.03125 while it waits ([pricing](/docs/pricing)). ## Where to get Kotlin | Source | Kotlin version on 25 September 2026 | Use it? | | ---------------------------------------- | ----------------------------------- | --------------------------------- | | Ubuntu 24.04 `kotlin` package (universe) | 1.3.31 | No: far older than 2.4.20 | | Official compiler zip, GitHub releases | 2.4.20 | Yes, for single files and scripts | | SDKMAN! (`sdk install kotlin`) | Latest | Yes, if you already use SDKMAN! | | Your project's Gradle wrapper | What the build names | Yes, for Gradle projects | Kotlin compiles to JVM bytecode and the jar runs on `java`, so every route also needs a JDK. Ubuntu's `openjdk-21-jdk-headless` (21.0.12.1 on 25 September 2026) is the usual choice; see [Java in a sandbox](/languages/java). ## Install, compile and run The command-line compiler comes as `kotlin-compiler-.zip`; unzip it and use the scripts in `kotlinc/bin`. A program compiles with `kotlinc hello.kt -include-runtime -d hello.jar` and runs with `java -jar hello.jar` ([Kotlin](https://kotlinlang.org/docs/command-line.html)). ```ts check import { Sandbox } from "withruntime"; const source = ` data class Score(val name: String, val points: Int) fun main() { val scores = listOf(Score("ada", 42), Score("lin", 57), Score("sam", 33)) println(scores.maxBy { it.points }.name) } `; const zip = "https://github.com/JetBrains/kotlin/releases/download/v2.4.20/kotlin-compiler-2.4.20.zip"; await using sbx = await Sandbox.create({ diskMiB: 8192, timeoutSeconds: 1200, onLeaseEnd: "stop" }); await sbx.exec( "sudo apt-get update -q && sudo apt-get install -y -q --no-install-recommends openjdk-21-jdk-headless", { check: true, timeoutMs: 600_000 }, ); await sbx.exec(`curl -fsSL -o kotlin.zip ${zip} && unzip -q kotlin.zip && rm kotlin.zip`, { check: true, timeoutMs: 300_000, }); await sbx.network.set({ internet: false }); // compile and run offline await sbx.files.write("/workspace/job/app.kt", source); const build = await sbx.exec( ["/workspace/kotlinc/bin/kotlinc", "app.kt", "-include-runtime", "-d", "app.jar"], { cwd: "/workspace/job", timeoutMs: 300_000 }, ); if (build.exitCode !== 0) console.error(build.stderr); const run = await sbx.exec(["java", "-jar", "app.jar"], { cwd: "/workspace/job", timeoutMs: 60_000, }); console.log(run.stdout); // lin ``` ```python check from withruntime import Sandbox source = """ data class Score(val name: String, val points: Int) fun main() { val scores = listOf(Score("ada", 42), Score("lin", 57), Score("sam", 33)) println(scores.maxBy { it.points }.name) } """ zip_url = "https://github.com/JetBrains/kotlin/releases/download/v2.4.20/kotlin-compiler-2.4.20.zip" with Sandbox.create(disk_mib=8192, timeout_seconds=1200, on_lease_end="stop") as sbx: sbx.exec("sudo apt-get update -q && sudo apt-get install -y -q --no-install-recommends " "openjdk-21-jdk-headless", check=True, timeout_ms=600_000) sbx.exec(f"curl -fsSL -o kotlin.zip {zip_url} && unzip -q kotlin.zip && rm kotlin.zip", check=True, timeout_ms=300_000) sbx.network.set(internet=False) # compile and run offline sbx.files.write("/workspace/job/app.kt", source) build = sbx.exec(["/workspace/kotlinc/bin/kotlinc", "app.kt", "-include-runtime", "-d", "app.jar"], cwd="/workspace/job", timeout_ms=300_000) if build.exit_code != 0: print(build.stderr) run = sbx.exec(["java", "-jar", "app.jar"], cwd="/workspace/job", timeout_ms=60_000) print(run.stdout) # lin ``` - The zip unpacks to `/workspace/kotlinc`, since commands start in the home folder, `/workspace`. - `-include-runtime` puts the Kotlin standard library in the jar, so plain `java` runs it. - Give the compiler a `timeoutMs` well above the 60-second default for a command; a build that runs out comes back with `timedOut: true` instead of throwing. - Compile errors are on `stderr`, ready to hand back to the model that wrote the code. ## A Gradle project For a project with `build.gradle.kts`, upload it, let the wrapper fetch Gradle and the dependencies, then test with the network off: ```ts check import { Sandbox } from "withruntime"; await using sbx = await Sandbox.create({ image: "kotlin", diskMiB: 10_240, timeoutSeconds: 3600, onLeaseEnd: "stop", }); await sbx.files.upload("./my-kotlin-app", "/workspace/app"); await sbx.exec("./gradlew --no-daemon build -x test", { cwd: "/workspace/app", check: true, timeoutMs: 1_800_000, }); await sbx.network.set({ internet: false }); const test = await sbx.exec(["./gradlew", "--no-daemon", "--offline", "test"], { cwd: "/workspace/app", timeoutMs: 1_800_000, onStdout: (text) => process.stdout.write(text), }); console.log("exit", test.exitCode); ``` ## Kotlin in every sandbox Put the JDK and the compiler in a [custom image](/docs/images). Recipe commands run as root in `/workspace`, so this unpacks the compiler into `/opt` and links its scripts into `/usr/local/bin`, which is on the sandbox user's `PATH`: ```ts check import { Runtime } from "withruntime"; const runtime = new Runtime(); await runtime.images.build({ name: "kotlin", recipe: { apt: ["openjdk-21-jdk-headless"], commands: [ "curl -fsSL -o /tmp/k.zip https://github.com/JetBrains/kotlin/releases/download/v2.4.20/kotlin-compiler-2.4.20.zip", "unzip -q /tmp/k.zip -d /opt && rm /tmp/k.zip", "ln -sf /opt/kotlinc/bin/kotlinc /opt/kotlinc/bin/kotlin /usr/local/bin/", ], }, }); await using sbx = await runtime.sandboxes.create({ image: "kotlin", network: { internet: false } }); const version = await sbx.exec(["kotlinc", "-version"]); console.log(version.stdout + version.stderr); ``` ```python check from withruntime import Runtime runtime = Runtime() runtime.images.build(name="kotlin", recipe={ "apt": ["openjdk-21-jdk-headless"], "commands": [ "curl -fsSL -o /tmp/k.zip https://github.com/JetBrains/kotlin/releases/download/v2.4.20/kotlin-compiler-2.4.20.zip", "unzip -q /tmp/k.zip -d /opt && rm /tmp/k.zip", "ln -sf /opt/kotlinc/bin/kotlinc /opt/kotlinc/bin/kotlin /usr/local/bin/", ], }) with runtime.sandboxes.create(image="kotlin", network={"internet": False}) as sbx: version = sbx.exec(["kotlinc", "-version"]) print(version.stdout + version.stderr) ``` The code interpreter does not run Kotlin; its JVM language is Java ([code interpreter](/docs/javascript#code-interpreter)). A sandbox made from this image has Java ready for it too. Building an image is free; a stored image is charged on its size. ## Related - [Run Java code in a sandbox](/languages/java) - [Grade student code](/use-cases/grade-student-code) - [A coding agent's sandbox](/use-cases/coding-agent-sandbox) - [Per-user dev environments](/use-cases/per-user-dev-environments) New accounts get 50 free sandbox hours, no card: ```bash no-run npx withruntime sandbox run --trial -- bash -c 'sudo apt-get update -q && sudo apt-get install -y -q openjdk-21-jdk-headless && java -version' ``` ## Sources - Kotlin command-line compiler: https://kotlinlang.org/docs/command-line.html (read 25 September 2026) - Kotlin compiler 2.4.20 release zip: https://github.com/JetBrains/kotlin/releases/tag/v2.4.20 (read 25 September 2026) - Ubuntu 24.04 package indexes (`kotlin` 1.3.31+ds1-1ubuntu1, `openjdk-21-jdk-headless` 21.0.12.1+1-1~24.04.4): http://archive.ubuntu.com/ubuntu/dists/noble/universe/binary-amd64/ and http://archive.ubuntu.com/ubuntu/dists/noble-updates/main/binary-amd64/ (read 25 September 2026) Facts on this page were checked on 25 September 2026.