Kotlin Multiplatform Mobile: Shared Logic, Native UI
Kotlin multiplatform mobile enables sharing business logic, networking, and data layers between Android and iOS while keeping native UI on each platform. Therefore, teams maintain the native look and feel users expect while eliminating duplicate business logic implementation. As a result, development velocity increases without sacrificing platform-specific user experiences. Crucially, KMP is a code-sharing strategy rather than a UI framework, which is exactly why it sidesteps the “uncanny valley” problems that plague abstraction-heavy cross-platform toolkits.
KMP Architecture Overview
The shared module contains platform-agnostic code including data models, repository patterns, and business rules. Moreover, expect/actual declarations provide a mechanism for platform-specific implementations within the shared codebase. Consequently, meaningful code-sharing ratios are achievable without compromising native capabilities — though the exact percentage depends heavily on how much of your app is logic versus UI. Compose Multiplatform extends the sharing opportunity to the UI layer for teams comfortable with declarative UI across platforms. Furthermore, the shared module can integrate with Swift Package Manager on iOS for cleaner dependency management.
The expect/actual Mechanism in Practice
The expect/actual pattern is how KMP reaches into platform APIs without leaking them into shared code. You declare an expected contract in commonMain and supply a concrete implementation in each target source set. A typical example is platform-specific storage or device identity.
// commonMain: the contract every platform must satisfy
expect class PlatformContext
expect fun createSettings(context: PlatformContext): Settings
expect val platformName: String
// androidMain: backed by SharedPreferences
actual typealias PlatformContext = android.content.Context
actual fun createSettings(context: PlatformContext): Settings {
val prefs = context.getSharedPreferences("app", Context.MODE_PRIVATE)
return SharedPreferencesSettings(prefs)
}
actual val platformName: String = "Android ${'