How KMP Works & What to Share
How one language targets many platforms
Kotlin can compile to several targets. This is what makes KMP possible:
- Kotlin/JVM — for Android (and servers). Your shared code becomes a normal library the Android app uses.
- Kotlin/Native — compiles to a native binary for iOS. Your shared code becomes a framework that Swift imports like any other.
- Kotlin/JS / Wasm — for the web.
So the same Kotlin source is compiled differently for each platform, producing native artifacts — not an interpreted layer. That’s why KMP performance is essentially native.
The layered way to think about an app
A typical mobile app has layers. KMP lets you draw a line: everything below the UI can be shared.
What’s easy to share vs what’s not
- Easy & high-value: models, networking, serialization, business logic, caching.
- Shareable with libraries: database (SQLDelight), dependency injection (Koin), date/time (kotlinx-datetime).
- Platform-specific (use expect/actual): things only the OS provides — secure storage, sensors, the exact platform name.
- Usually native: the UI (unless you adopt Compose Multiplatform).
A pragmatic adoption strategy
You don’t have to convert a whole app at once. A proven path:
- Start by sharing one focused module — commonly the networking + models layer.
- Prove it works in both apps.
- Gradually move repositories and business logic into shared code.
- Optionally share presentation logic (ViewModels), then maybe UI later.
Common mistakes
- Trying to share everything (including UI) on day one — start small.
- Putting platform-specific code in common (it won’t compile for all targets).
- Underestimating the value of just sharing models + networking — it’s often the biggest win.
Summary: Kotlin compiles to JVM (Android), Native (iOS) and JS/Wasm (web), producing native artifacts. Share everything below the UI — models, networking, logic — and adopt KMP gradually, starting with one module.