Multiplatform projects
A Kargo project can target several platforms at once: jvm, wasm, js, native and android. Code in src/ is compiled for all of them; code in src-<target>/ only for one.
Create a multiplatform project
Section titled “Create a multiplatform project”kargo new hello -t jvm,wasm,native[package]name = "hello"version = "0.1.0"group = "com.example"
[target.jvm]
[target.wasm]environment = "js"
[target.native]platforms = ["host"]kind = "executable"To add a target to an existing project, use kargo target add:
kargo target add wasm nativeIt appends the same [target.<name>] sections kargo new writes, without touching the rest of kargo.toml, and creates an empty src-<target>/ for platform-specific code. kargo target remove wasm disables a target again (its sources stay on disk), and kargo target list shows what is enabled. See kargo target.
Sharing code with expect/actual
Section titled “Sharing code with expect/actual”Declare what you need in common code with expect, then provide an actual for every target:
package com.example.hello
expect fun platformName(): String
fun greeting(): String = "Hello from ${platformName()}!"
fun main() { println(greeting())}package com.example.hello
actual fun platformName(): String = "the JVM (Java ${System.getProperty("java.version")})"package com.example.hello
actual fun platformName(): String = "WebAssembly"package com.example.hello
import kotlin.experimental.ExperimentalNativeApi
@OptIn(ExperimentalNativeApi::class)actual fun platformName(): String = "Kotlin/Native on ${Platform.osFamily}"Build, run and test each target
Section titled “Build, run and test each target”$ kargo build # all targets$ kargo run # the first of: jvm, native, wasm, js, androidHello from the JVM (Java 21.0.5)!$ kargo run -t nativeHello from Kotlin/Native on LINUX!$ kargo run -t wasmHello from WebAssembly!$ kargo test # tests on every target$ kargo test -t native$ kargo test --no-fail-fast # keep testing the other targets when one failskargo test stops at the first target that fails; --no-fail-fast (or [test] fail-fast = false) tests them all and prints a result per target. kargo build --keep-going builds every target and reports each failure. See Testing every target.
JavaScript next to WebAssembly
Section titled “JavaScript next to WebAssembly”[target.js] compiles the same common code to JavaScript with Kotlin/JS, for consumers that can’t use Wasm. Its own code goes in src-js/ and tests-js/, and its own dependencies in [target.js.dependencies]:
[target.jvm]
[target.js]environment = "node"package com.example.hello
actual fun platformName(): String = "Kotlin/JS"$ kargo run -t jsHello from Kotlin/JS!Wasm and JS are separate targets in Kargo, as in Gradle (wasmJs() and js()), so a project that enables both writes an actual for each. See JavaScript.
Dependencies
Section titled “Dependencies”Multiplatform libraries go in [dependencies]; Kargo picks the right artifact for each target using Gradle module metadata. Platform-specific libraries go in [target.<name>.dependencies]:
[dependencies]"org.jetbrains.kotlinx:kotlinx-datetime" = "0.7.1""com.squareup.okio:okio" = "3.10.2"
[target.jvm.dependencies]"org.slf4j:slf4j-simple" = "2.0.17"Using a JVM-only library in src/ fails to compile on the other targets. That’s your cue to move the code to src-jvm/.
- Keep business logic in
src/and put only the thin platform layer insrc-<target>/. - Prefer multiplatform libraries (klibs.io lists them) over
java.*APIs in common code. For example, usekotlinx-datetimeinstead ofjava.time, andokioorkotlinx-iofor files. - Tests in
tests/run on every target, which is a cheap way to catch platform differences. kargo docdocumentssrc/as common code and shows which platforms each declaration is available on. See API documentation.- In an editor,
kargo lsptreatssrc/and eachsrc-<target>/as separate source sets, soexpectandactualdeclarations link up and common code only sees common code and the libraries every target has. Kargo’s own Kotlin server reads the code of every target; with JetBrains’ Kotlin LSP, common code is analyzed as JVM code and Wasm, JS and Native code gets no Kotlin code intelligence yet. See Multiplatform projects. kargo publishpublishes a multiplatform library the way the Kotlin Gradle Plugin does, with one module per platform, so Gradle and Kargo projects pick the right artifact. See Publishing a library.