Kotlin Multiplatform
Prerequisites: Gradle basics, Coroutines: the basics
Kotlin Multiplatform (KMP) lets you share code between platforms — Android, iOS, desktop, web, and server — while still writing platform-specific code where it matters. Unlike some cross-platform approaches, you decide how much to share: just business logic, or the user interface too.
How a KMP project is organized
shared/
└── src/
├── commonMain/kotlin/ # code for every platform
├── androidMain/kotlin/ # Android-specific code
└── iosMain/kotlin/ # iOS-specific code (compiled to native)
androidApp/ # the Android app, uses :shared
iosApp/ # the Xcode project, uses the shared framework
Code in commonMain can use only multiplatform libraries — the Kotlin
standard library, kotlinx.coroutines, kotlinx.serialization,
kotlinx-datetime, Ktor Client, SQLDelight, and many more.
expect and actual
When common code needs a platform feature, declare it with expect and
implement it per platform with actual:
// commonMain
expect fun platformName(): String
class Greeting {
fun greet() = "Hello from ${platformName()}!"
}
// androidMain
actual fun platformName(): String = "Android ${android.os.Build.VERSION.SDK_INT}"
// iosMain
import platform.UIKit.UIDevice
actual fun platformName(): String =
UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
The iOS version calls Apple's UIKit directly — Kotlin/Native can use iOS
frameworks. In many cases, an interface in common code with
platform-specific implementations (passed in through dependency
injection) is a simpler alternative to expect/actual.
Calling shared code from Swift
The shared module compiles to an iOS framework, which Swift imports like any other:
import Shared
let message = Greeting().greet()
Compose Multiplatform
Compose Multiplatform (from JetBrains) extends Jetpack Compose to iOS, desktop, and web, so the UI can be shared as well. Teams choose between sharing only logic (native UI on each platform, written in SwiftUI and Compose) or sharing both.
When to use it
KMP suits teams that ship on Android and iOS and want one implementation of networking, validation, and business rules, without giving up native performance or platform APIs. Start small — share one module, such as the networking layer — and expand as the team gains confidence.