Kotlin Multiplatform Compose — Complete Guide
In this tutorial, you'll learn about Kotlin Multiplatform Compose. We cover key concepts, practical examples, and best practices.
The Problem
Your Compose Multiplatform project doesn't render on iOS, or you're using Android-specific composables that don't exist on iOS.
Wrong Approach ❌
// Using Android-only composables
@Composable
fun MyScreen() {
// AndroidView — doesn't exist on iOS!
AndroidView(factory = { View(it) }) { }
}
Output: Compilation error on iOS target. Shared UI doesn't work.
Right Approach ✅
// build.gradle.kts (shared module)
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose") version "1.6.10"
id("org.jetbrains.kotlin.plugin.compose")
}
kotlin {
androidTarget()
listOf(iosX64(), iosArm64(), iosSimulatorArm64()).forEach { target ->
target.binaries.framework {
baseName = "shared"
isStatic = true
}
}
sourceSets {
commonMain.dependencies {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.ui)
}
}
}
// commonMain — shared composables
@Composable
fun App() {
MaterialTheme {
var count by remember { mutableStateOf(0) }
Scaffold(
topBar = { TopAppBar(title = { Text("KMP Compose") }) },
floatingActionButton = {
FloatingActionButton(onClick = { count++ }) {
Icon(Icons.Default.Add, "Add")
}
}
) { padding ->
Column(
modifier = Modifier.padding(padding).fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text("Count: $count", style = MaterialTheme.typography.headlineLarge)
Button(onClick = { count = 0 }) { Text("Reset") }
}
}
}
}
// platform-specific entry points
// androidMain
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent { App() }
}
}
// iosMain
import androidx.compose.ui.window.ComposeUIViewController
fun MainViewController() = ComposeUIViewController { App() }
Output: Shared Compose UI renders on both Android and iOS.
Prevention
- Use only multiplatform-compatible Compose APIs (
compose.foundation,compose.material3). - Use
expect/actualfor platform-specific UI (e.g., camera preview, maps). - Use
org.jetbrains.composeplugin, not Android-onlycomposeplugin. - Test UI on both platforms.
Common Mistakes with multiplatform kmp compose
- Mixing let bindings with <- bindings in do notation, producing type errors
- Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
- Non-exhaustive pattern matches that compile with warnings then crash at runtime
These mistakes appear frequently in real-world KOTLIN code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro