On this page
Teams building for Android and iOS face a choice: write everything twice, share logic, or share logic and UI. Kotlin Multiplatform makes the second option practical. Compose Multiplatform extends it to the third, and you can mix both per screen.
What each one shares
Kotlin Multiplatform (KMP)
KMP compiles shared Kotlin to JVM bytecode for Android and native binaries for iOS. Typically shared: networking (Ktor), persistence (Room KMP or SQLDelight), serialization, business rules, and often ViewModels. AndroidX libraries such as Lifecycle ViewModel, Room and DataStore offer multiplatform support. Check each library's current status before relying on it.
Platform-specific APIs are accessed through expect/actual declarations or interfaces injected per platform:
// commonMain
expect fun platformName(): String
// androidMain
actual fun platformName(): String = "Android ${android.os.Build.VERSION.SDK_INT}"
// iosMain
actual fun platformName(): String =
platform.UIKit.UIDevice.currentDevice.systemName() + " " +
platform.UIKit.UIDevice.currentDevice.systemVersionMany teams prefer interfaces plus DI over expect/actual for larger platform services, because they're easier to fake in tests.
Compose Multiplatform (CMP)
CMP, by JetBrains, brings the Compose UI programming model to iOS, desktop and web (web is less mature). Compose Multiplatform for iOS has been stable since version 1.8.0 (2025). Shared composables live in commonMain:
@Composable
fun GreetingScreen(viewModel: GreetingViewModel) {
val state by viewModel.state.collectAsStateWithLifecycle()
MaterialTheme {
Column(Modifier.fillMaxSize().padding(16.dp)) {
Text("Hello from ${state.platform}", style = MaterialTheme.typography.headlineSmall)
Button(onClick = viewModel::refresh) { Text("Refresh") }
}
}
}On iOS, the shared UI is hosted in a UIViewController and can be embedded in SwiftUI, and SwiftUI or UIKit views can be embedded inside Compose when needed.
Typical project structure
composeApp/ (or shared/)
src/commonMain/ shared Kotlin (+ shared UI with CMP)
src/androidMain/ Android actuals, Android-only code
src/iosMain/ iOS actuals
iosApp/ Xcode project hosting the shared frameworkComparison
| KMP (logic only) | CMP (logic + UI) | |
|---|---|---|
| Code shared | Data, domain, often ViewModels | Plus UI |
| UI feel | Fully native on each platform | Same UI everywhere; adapt per platform where needed |
| iOS team involvement | Swift UI developers consume a Kotlin framework | Mostly Kotlin; iOS expertise still needed for integration |
| Adoption path | Incremental, module by module | Screen by screen, or new apps |
| Best when | Platform-native UX is a priority | Speed and consistency matter more than native look |
Trade-offs to weigh
Benefits
- One implementation of business logic and bugs fixed once
- Kotlin skills reused across platforms
- Incremental adoption: keep existing native apps
Costs
- iOS build tooling and debugging take learning
- Library availability for multiplatform varies
- Platform-specific UX conventions need care with shared UI
How to decide
- Existing native apps? Start with KMP for one shared module (for example networking or a domain module).
- New app, small team? CMP can cover both platforms quickly. Prototype your hardest screen on iOS first.
- Heavy platform integration (camera pipelines, widgets, Watch, CarPlay)? Keep those parts native.
- Evaluate libraries you depend on for multiplatform support before committing.
Troubleshooting
- iOS build slow: native compilation is slower than JVM. Build only the needed targets during development.
- Coroutines and Flow from Swift: consider community tools that generate Swift-friendly async wrappers, or expose callback-based APIs at the boundary.
- Missing API in commonMain: define an interface and implement it per platform.
Frequently asked questions
Is KMP the same as Flutter or React Native?
No. KMP shares logic while allowing native UI, and compiles to native code without a separate runtime bridge. CMP is closer to Flutter in sharing UI, but keeps Kotlin and Android's Compose model.
Does Google support KMP?
Google's Android documentation covers KMP and several AndroidX libraries publish multiplatform artifacts. JetBrains leads KMP and CMP.
Can I share ViewModels?
Yes. The AndroidX Lifecycle ViewModel has multiplatform support, and community libraries exist too.
Conclusion
Kotlin Multiplatform shares logic while keeping native UI; Compose Multiplatform shares UI as well. Start small with a shared module, prototype your hardest screens, and keep deeply platform-specific features native.
Next step: run reliable background tasks with WorkManager and Background Work.
Official references
๐ฑ Apps built by Yunok Tech
Real Android apps on Google Play, free to download.
Walzi4K wallpapers for lock and home screenGet it โธ
NotiVaultNotification history: recover dismissed notificationsGet it โธ
Ready to build real Android applications?
Jetpack Compose clicks once you build real screens with real state. Practise modern Android UI development on projects that go beyond toy examples.
Move beyond theory and strengthen your Android development skills with Yunoktech's Android course. Learn core concepts, practical implementation, modern Android development techniques, and the reasoning behind building maintainable applications.
Explore the Android course and take your next step as an Android developer.