What is Kotlin Multiplatform Mobile (KMM), and what would you actually share between iOS and Android with it?
KMM is not a UI framework in disguise — it compiles one Kotlin source set to real native code on both platforms, and the honest answer is how narrow its sharing boundary is meant to be.
LEARN BY DOINGPut your intuition to work3 steps
What is Kotlin Multiplatform Mobile (KMM), and what would you actually share between iOS and Android with it?
Use the lesson’s examples and explanation to check your idea.
Personal reflection. Nothing is sent to an AI service.This question tests whether a candidate understands KMM as a targeted tool for a specific problem — duplicated business logic across two native codebases — rather than as "Flutter with Kotlin." That distinction matters, because the honest scope of KMM is much narrower than a full cross-platform UI framework, and knowing exactly where that boundary sits is the senior answer.
#What KMM actually is
Kotlin Multiplatform Mobile lets you write Kotlin once in a commonMain source set and compile it to two different targets: JVM bytecode for Android (it runs exactly like any other Android module) and a native binary via Kotlin/Native, compiled ahead-of-time through LLVM into a .framework that Xcode links like any other Objective-C/Swift framework. There is no interpreter and no bridge at runtime on either side — each platform gets real, compiled, native code for the shared logic.
Code that needs a platform-specific implementation is declared with expect in commonMain and implemented with actual in each platform source set:
// commonMainexpect fun getPlatformName(): Stringclass Greeting {fun greet(): String = "Hello from ${getPlatformName()}"}
// androidMainactual fun getPlatformName(): String = "Android"
// iosMainactual fun getPlatformName(): String = "iOS"
#What you actually share — and what you never do
The parts of an app that are genuinely platform-independent logic are the ones worth sharing: networking (typically Ktor client), JSON handling (kotlinx.serialization), the domain/business-rule layer, local persistence (SQLDelight, which generates typed Kotlin from SQL and compiles to each platform's native database driver), dependency injection wiring (Koin works well multiplatform), and validation logic. A shared repository looks like ordinary Kotlin:
// commonMain@Serializabledata class User(val id: String, val name: String)class UserRepository(private val client: HttpClient) {suspend fun fetchUser(id: String): User =client.get("https://api.example.com/users/$id").body()}
What you deliberately do not share is the UI. Android keeps Jetpack Compose, iOS keeps SwiftUI (or UIKit); each platform's UI is written natively, on purpose, so the app keeps native performance, native platform conventions, and access to the newest platform APIs on day one without waiting on a cross-platform framework to catch up. KMM's job stops at the data and domain layer.
#The part that trips people up: coroutines crossing into Swift
A shared ViewModel-shaped class exposing state with coroutines and StateFlow works fine on the Kotlin side:
class UserViewModel(private val repo: UserRepository) {private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())private val _state = MutableStateFlow<UiState>(UiState.Loading)val state: StateFlow<UiState> = _state.asStateFlow()fun load(id: String) {scope.launch {_state.value = UiState.Loading_state.value = runCatching { repo.fetchUser(id) }.fold(UiState::Loaded, UiState::Error)}}}
The catch is that Swift has no native concept of a Kotlin coroutine or a Flow, so a raw suspend fun or StateFlow exposed to iOS is awkward to consume as-is. Most teams reach for a bridging library (SKIE or KMP-NativeCoroutines are the common choices) that generates Swift-friendly async/await functions and AsyncSequence wrappers over the Kotlin coroutine API, rather than hand-rolling completion-handler wrappers for every suspend function.
🧠 KMM sharing boundaries
0/2 · 0/2 answered1. What does KMM compile commonMain code to for the iOS target?
2. Which layer does a KMM setup typically NOT share between iOS and Android?