Skip to main content

Kotlin Multiplatform and Compose Multiplatform: Multi-Native Mobile in 2026

11 min read Updated May 31, 2026
Share:
On this page (19sections)

React Native and Flutter walked so Kotlin Multiplatform could run. That line is a hot take — but after spending real project time in Kotlin Multiplatform (KMP) and Compose Multiplatform (CMP), I do not expect to go back to traditional hybrid stacks for the kind of products I build.

This is not a marketing slide. It is the honest engineer-to-engineer breakdown I wish I had when evaluating our 2026 mobile stack: what KMP actually is, how the architecture works, who ships it in production, where Compose on iOS still needs care, and how it compares to React Native and Flutter on numbers that matter.

The short version

KMP is not “another hybrid framework.” It is a different philosophy:

  • You do not ship a runtime — you compile to true native binaries.
  • You do not fake native — you share logic, then use real SwiftUI, UIKit, or Compose for UI.
  • You do not choose 80% native OR 100% shared — you choose per screen, per module, per team.

If you already write Jetpack Compose on Android, you are most of the way there. One Kotlin codebase can target Android, iOS, Web, and Desktop — with platform-specific UI only where you decide you need it.

The future of cross-platform mobile is not hybrid. It is multi-native.

Hybrid vs multi-native: what actually ships in your APK/IPA

Traditional hybrid stacks bundle an interpreter or bridge:

ApproachWhat runs on deviceUI renderingTypical shared surface
React NativeJavaScript + native modules via bridgeNative components driven from JSJS/TS logic + React components
FlutterDart VM + Skia engineSkia-drawn widgets (not native controls)Dart UI + logic (~100%)
Kotlin MultiplatformCompiled Kotlin → platform codeNative (Compose, SwiftUI, UIKit)Kotlin logic; UI optional per target
Compose MultiplatformCompiled KotlinCompose runtime on each platformKotlin UI + logic when you opt in

Bridge cost (React Native): Meta’s own architecture docs describe the async JavaScript-to-native bridge as a serialization bottleneck. New Architecture (JSI, Fabric, TurboModules) reduces but does not eliminate that boundary. For animation-heavy or chat-style UIs, bridge chatter still shows up in profiles.

Engine cost (Flutter): You ship Skia and the Dart runtime. App size and memory footprints are predictable but not zero — Flutter’s FAQ notes minimum overhead compared to a minimal native app. You gain pixel consistency; you trade away native control widgets on every screen.

KMP cost: Shared Kotlin compiles to JVM bytecode on Android, native ARM/x64 on iOS (via Kotlin/Native), and analogous targets elsewhere. No JS bridge. No Dart VM in your process unless you add one yourself.

Architecture: how a production KMP app is layered

Most successful teams do not start with 100% shared UI. They start with a shared core and native (or Compose) shells.

┌─────────────────────────────────────────────────────────────────┐
│                     Presentation (per platform)                  │
│  Android: Jetpack Compose    iOS: SwiftUI / UIKit / CMP         │
│  Desktop: Compose Desktop    Web: Compose for Web (optional)    │
└───────────────────────────────┬─────────────────────────────────┘
                                │ ViewModels, UI state (often shared)
┌───────────────────────────────▼─────────────────────────────────┐
│                     Shared feature modules (KMP)                 │
│  Use cases · Repositories · Domain models · Validators           │
└───────────────────────────────┬─────────────────────────────────┘

┌───────────────────────────────▼─────────────────────────────────┐
│                     Shared infrastructure (KMP)                  │
│  HTTP client (Ktor) · Serialization (kotlinx.serialization)      │
│  Coroutines · Settings · Analytics event builders                │
└───────────────────────────────┬─────────────────────────────────┘
                                │ expect/actual or interfaces
┌───────────────────────────────▼─────────────────────────────────┐
│                     Platform adapters                              │
│  Android: Room, WorkManager    iOS: Core Data, BGTaskScheduler    │
│  Secure storage, push tokens, billing SDK wrappers                 │
└─────────────────────────────────────────────────────────────────┘

Module map (Gradle)

A Gradle structure that scales to multiple features without turning into a ball of mud:

my-app/
├── shared/
│   ├── core/                 # logging, dispatchers, result types
│   ├── network/              # Ktor, API models
│   ├── domain/               # use cases, pure Kotlin
│   └── feature-login/        # login repository + ViewModel
├── androidApp/               # Compose Activity, Hilt, Room
├── iosApp/                   # Xcode project, SwiftUI shell
└── desktopApp/               # optional Compose Desktop entry

expect/actual (or interface + platform implementations) is the escape hatch. Shared code declares expect fun openUrl(url: String); Android and iOS provide actual implementations. That is how you keep Keychain and EncryptedSharedPreferences behind one Kotlin interface.

Data flow (MVVM-friendly)

This aligns with Clean Architecture on Android — the same layers, exported into commonMain:

  1. UI collects user events (Compose, SwiftUI, or both).
  2. ViewModel (often in commonMain) exposes StateFlow UI state.
  3. Use case orchestrates domain rules — pure Kotlin, easy to unit test on JVM.
  4. Repository merges remote and local sources.
  5. Platform adapters implement storage, permissions, and SDK calls.

If you already use MVVM on Android, see our Android MVVM guide — the mental model transfers directly; the ViewModel simply moves up one Gradle module.

The numbers: adoption, ecosystem, and momentum

These are the figures I use when talking to platform leads — all linked to primary sources so you can verify before a roadmap meeting.

MetricFigureSource
Kotlin on Android~93% of top 1,000 Google Play apps use Kotlin (2024)Android Developers Blog — State of Kotlin on Android
KMP project growth2×+ year-over-year increase in KMP projects indexed by JetBrains (2023 survey)Kotlin Multiplatform in 2023 — JetBrains
Compose Multiplatform targetsAndroid, iOS, Desktop, Web from one Compose UI codebaseCompose Multiplatform — JetBrains
Official stabilityKMP Stable as of Kotlin 1.9.20 (Nov 2023)Kotlin 1.9.20 release
Google + JetBrains alignmentAndroid Jetpack libraries migrating to KMP-compatible artifactsAndroidX multiplatform announcements

Who ships KMP in production?

JetBrains maintains a public case studies page — these are not slide-deck logos; they are teams that published engineering write-ups:

CompanyWhat they shareNotes
NetflixProduct reliability toolingProduction Focused Kotlin Multiplatform — Netflix TechBlog
McDonald’sMobile SDK and shared logic across marketsReferenced in KotlinConf case studies
Cash App (Block)Shared business logic between Android and iOSSquare/Block engineering talks on KMP for payments flows
ForbesContent and authentication layersKotlin Multiplatform adoption for reader apps
Philips, VMware, 9GAGVarious shared coresListed with technical detail on kotlinlang.org

Takeaway: KMP is past the “only startups experiment” phase. Large consumer and enterprise apps share networking, models, and feature logic today. UI strategy varies — some teams are Compose-heavy; others keep SwiftUI and use KMP strictly below the presentation layer.

Why teams quietly switch

1. True native performance

Shared Kotlin on iOS compiles to native machine code through Kotlin/Native. Hot paths do not cross a JavaScript bridge. Compose Multiplatform on iOS uses Skia (similar rendering model to Flutter for Compose-drawn pixels) — but you can render only the screens you choose with Compose and keep the rest in SwiftUI.

2. Granular control

You are not locked into a single UI paradigm:

  • Share everything except the iOS settings screen.
  • Share ViewModels but not composables.
  • Share nothing UI-related for release 1 — only domain + data — and add CMP in release 2.

That per-screen knob is hard to replicate in RN or Flutter without platform channels or federated plugins.

3. Jetpack Compose skills transfer

Google invests in Compose on Android; JetBrains invests in Compose Multiplatform. The @Composable mental model, state hoisting, and Navigation Compose patterns you learn for Android apply on iOS and Desktop with documented deltas. If your team already standardized on Compose, CMP lowers the second-platform cost compared to learning SwiftUI from zero — though Apple HIG still matters for polish.

4. Ecosystem fit for backend-heavy teams

Kotlin is the same language many teams use on Ktor, Spring, and Gradle. Sharing DTOs, validation, and client SDKs between mobile and server (via Kotlin Multiplatform libraries) is underrated — fewer “the API changed and three repos drifted” incidents.

Compose Multiplatform on iOS: production-ready or not yet?

Honest answer: it depends on your risk tolerance and UI complexity.

Ready enough for many teams:

  • Standard form flows, lists, settings, auth wizards
  • Apps already theming Compose on Android and wanting visual parity
  • Internal tools and B2B apps where App Store pixel perfection is secondary

Still exercise caution:

  • Heavy platform integrations (Live Activities, complex maps, ARKit)
  • Highly custom transitions matching iOS system feel
  • Large legacy UIKit codebases where incremental SwiftUI migration is already underway

JetBrains marks Compose Multiplatform for iOS as a major focus with regular releases; check the release notes before you freeze versions. My rule: prototype the three hardest screens in week one. If scrolling, keyboard inset, and accessibility are acceptable, proceed. If not, default to shared ViewModels + SwiftUI.

For App Store packaging, distribution, and review pitfalls, pair this guide with Apple distribution strategies and the iOS submission prerequisites checklist.

Comparison scorecard (2026 evaluation)

Subjective but grounded in field experience — use it as a discussion starter, not a verdict.

CriterionReact NativeFlutterKMP + CMP
Time-to-first-screen (greenfield)FastFastest uniform UIModerate (Gradle + Xcode setup)
Peak native performanceGood with New ArchitectureVery good; Skia everywhereExcellent when UI is native; very good with CMP
Hiring poolLargest JS/React poolStrong Dart/Flutter poolStrong Android/Kotlin pool; iOS still needed
UI fidelity to platform HIGGood with platform componentsConsistent but “non-native” feelExcellent when using SwiftUI/UIKit
Shared UI percentageHigh~100%Your choice (0–100%)
App size overheadModerate (Hermes + bundles)Moderate (engine)Lower for logic-only sharing
Web + desktop bonusReact Native Web (extra stack)Flutter Web/DesktopCompose Multiplatform Desktop/Web

A practical adoption path (90 days)

Days 1–14 — Spike

  • Create shared module with one API call (Ktor) and one repository.
  • Wire Android Compose screen to shared ViewModel.
  • Expose same ViewModel to a minimal SwiftUI screen on iOS.
  • Measure: build times, iOS binary size delta, developer ergonomics.

Days 15–45 — First feature module

  • Migrate one bounded feature (e.g. login or profile) to shared domain + data.
  • Keep UI native on iOS if CMP feels risky; use Compose on Android.
  • Add unit tests in commonTest — this is where KMP pays off fastest.

Days 46–90 — Platform hardening

  • expect/actual for secure storage, analytics, feature flags.
  • CI: :shared:check, Android instrumented tests, iOS xcodebuild on simulator.
  • Document which screens are shared UI vs native in your developer checkpoints list.

What I would tell Flutter and React Native devs

If you are on React Native: You likely stay because of JavaScript talent density, Expo velocity, and Meta’s ecosystem. Fair. KMP becomes interesting when bridge jank, native module maintenance, or type safety across the stack hurts — not because Kotlin is fashionable.

If you are on Flutter: You likely stay because one UI codebase genuinely works for your product shape. KMP + CMP competes most directly here — both target “write once, adjust per platform.” The difference is who owns the pixels: Flutter always Skia; CMP mixes Compose-rendered and truly native screens in one app.

If you are Android-first: You have the shortest path. Your existing Jetpack architecture, Gradle fluency, and Compose skills are the onboarding.

Closing take

Evaluating your 2026 mobile tech stack is not about picking the winner on Twitter. It is about where you want shared code to live, how much native feel you owe your users, and what your team already knows.

Kotlin Multiplatform did not replace React Native or Flutter overnight. It gave Android-heavy and Kotlin-native teams a credible way to share real logic — and, when ready, real Compose UI — without shipping someone else’s runtime in every build.

The question is not “hybrid or native.” It is how multi-native you want to be, screen by screen.


Originally sparked by a LinkedIn discussion on KMP vs hybrid stacks — expanded here with architecture diagrams, sources, and links for a full technical read.

Frequently Asked Questions

Is Kotlin Multiplatform just another hybrid framework like React Native?
No. KMP compiles shared Kotlin to platform-native binaries. There is no JavaScript bridge, no Dart VM, and no single runtime shipped inside your app. You share business logic (and optionally UI with Compose Multiplatform), then call real platform APIs and native UI toolkits where it matters.
Is Compose Multiplatform production-ready for iOS?
For greenfield apps and teams already on Jetpack Compose, CMP on iOS is viable in production today — with caveats. Mature teams often share UI on Android and iOS for standard screens, and drop to SwiftUI or UIKit for platform-specific flows (camera, widgets, deep OS integrations). Always prototype your heaviest screens first.
Should we migrate from Flutter or React Native to KMP?
Only if your pain is architectural, not political. If bridge latency, bundle size, or hiring Kotlin talent is the blocker, KMP is worth a spike. If your team ships fast on Flutter/RN and users are happy, migration cost rarely pays off. Run a two-sprint proof of concept on one feature module before committing.
What can we realistically share with KMP?
Most teams start with networking, serialization, validation, domain models, repositories, analytics event builders, and feature flags — typically 60–80% of non-UI code. UI sharing grows as Compose Multiplatform matures; navigation and design systems are still the hardest parts to unify.

Related Tutorials

Search tutorials