Kotlin Multiplatform is appearing everywhere in mobile engineering discussions.
JetBrains describes it as a production-ready way to share Kotlin code across Android, iOS, desktop, web, and server targets while retaining native platform capabilities. Google supports using it to share business logic between Android and iOS, and Compose Multiplatform for iOS reached stable status in 2025. The ecosystem is now mature enough to deserve serious evaluation.
That does not make the usual “KMP will replace Flutter” conclusion useful.
Kotlin Multiplatform is not simply another framework trying to build the same application from one codebase. Its more important idea is architectural:
Share the parts of a product that must behave identically, while keeping the parts that benefit from platform ownership.
That makes KMP less dramatic than the “write once, run everywhere” pitch. It also makes it potentially more significant for established mobile organisations.
The real question is not whether Kotlin Multiplatform will kill Flutter or React Native. It is whether a team should build a fully shared application, a selectively shared system, or a deliberate combination of native and shared code.
KMP and Compose Multiplatform are different decisions
A large percentage of cross-platform comparisons begin with the wrong abstraction.
Kotlin Multiplatform, or KMP, allows teams to share Kotlin code across Android, iOS, desktop, web, and backend targets. Teams can share networking, persistence, domain rules, validation, state machines, or application services while keeping the interface native.
Compose Multiplatform, or CMP, adds the option to share the user interface using the Compose programming model.
This distinction matters because plain KMP is not a direct replacement for Flutter or React Native. KMP without shared UI competes more directly with duplicated native business logic. Compose Multiplatform is the layer that competes with Flutter and React Native as a shared UI solution.
The official Kotlin comparison presents KMP as a spectrum. A team can share one small module, most application logic, or almost the entire product including UI. Flutter follows a different model: the framework normally owns both UI and application logic across targets.
That difference affects architecture, hiring, testing, debugging, and release ownership.
Why the momentum is real
KMP is no longer only an experimental side project.
Kotlin Multiplatform became stable in November 2023. Google later announced official support for sharing business logic between Android and iOS, and Android Studio provides a shared-module template for introducing KMP into an existing application.
Compose Multiplatform for iOS reached stable and production-ready status with version 1.8.0 in May 2025. The 1.11.0 release in 2026 continued improving iOS rendering, text input, and multiplatform UI testing.
Those milestones matter because KMP now has support at several levels:
- Kotlin is already deeply established in Android development.
- Google supports KMP for shared mobile business logic.
- JetBrains owns the language, compiler, IDE ecosystem, and Compose Multiplatform direction.
- More Jetpack libraries are becoming multiplatform-compatible.
- Production teams are publishing adoption stories instead of only prototypes.
However, “stable” does not mean “equally mature on every target.” It also does not remove the organisational cost of introducing another shared layer.
Technical readiness and operational readiness are separate decisions.
KMP’s strongest feature is adoption granularity
KMP discussions often lead with native compilation. Shared Kotlin code can compile to JVM bytecode on Android and platform-native binaries for iOS. There is no JavaScript runtime sitting between shared business logic and the platform.
That is useful, but performance is not KMP’s most strategically important property.
Its strongest feature is adoption granularity.
A team does not need to rewrite its application. It can begin with one bounded problem:
- authentication rules
- API models
- pricing calculations
- experimentation assignment
- offline synchronisation
- data validation
- local persistence
- a shared SDK
- an analytics state machine
The rest of the Android and iOS applications can remain native.
This is a fundamentally different migration model from introducing a framework whose strongest value appears when it owns a meaningful part of the presentation layer. KMP can create value before it owns a single screen.
The production use case is shared product truth
The strongest KMP case is not “we can reuse more code.” It is “we can stop two products from disagreeing about the same rule.”
Imagine separate Android and iOS experimentation libraries. Both are intended to assign users to the same experiment and record the same result. Over time, their implementations drift. The code is duplicated, but the deeper problem is duplicated product truth.
If the platforms assign users differently, the resulting data becomes unreliable. The same pattern applies to authentication policy, pricing, offline synchronisation, validation, and state transitions.
A shared module can move the business-critical behaviour and its tests into one place:
Shared Kotlin module
├── experiment rules
├── assignment engine
├── state machine
└── shared test suite
Android integration
├── Android analytics
├── Android storage
└── Android networking
iOS integration
├── iOS analytics
├── iOS storage
└── iOS networking
The important behaviour is implemented once. Platform-specific infrastructure remains where the existing teams understand it best.
A safe migration can run the new implementation beside the old one, compare outputs, use feature flags as kill switches, and remove the legacy path only after the behaviour is observable.
The success of KMP in production is not created by the compiler alone. It comes from controlled rollout, measurable behaviour, clear platform boundaries, and an exit strategy.
KMP is also an organisational architecture
The shared module creates a place where Android and iOS engineers can collaborate on the same product behaviour. That can reduce duplicated decisions and make knowledge more transferable between platform teams.
The transition is not automatic, though.
An iOS team still needs to evaluate binary size, startup performance, deployment, debugging, crash symbolication, API usability, and the ability to reverse the decision. Xcode and Swift interoperability also remain part of the daily experience, not a footnote in the architecture diagram.
This exposes one of the most important KMP trade-offs:
Shared code can create shared ownership, but it can also quietly turn Android engineers into owners of a dependency consumed by iOS engineers.
A technically clean KMP module can still produce an unhealthy team boundary when:
- only Android developers understand the shared code;
- iOS developers cannot debug failures independently;
- public APIs expose Kotlin-specific concepts awkwardly to Swift;
- every change requires the Android team;
- shared-module releases block native releases;
- nobody owns cross-platform integration quality.
The architecture needs an ownership model, not only a commonMain folder.
Where the hype begins
KMP becomes hype when its flexibility is presented as zero-cost optionality.
“You can share anything from 1% to 100%” is technically appealing. It does not answer the difficult questions:
- Which layers should actually be shared?
- Who owns the shared module?
- How will Swift developers consume asynchronous Kotlin APIs?
- How will crashes from shared code appear in iOS tooling?
- Which libraries behave consistently across targets?
- What happens when a required SDK has no KMP implementation?
- Are teams sharing logic because it is identical, or merely because sharing is possible?
A technology can be production-ready and still require experienced engineers. Those statements are not contradictory.
Compose Multiplatform is the actual Flutter competitor
Once Compose Multiplatform owns the UI, the comparison changes.
KMP with native UI means:
Shared logic + separate native UI
Compose Multiplatform means:
Shared logic + shared Compose UI
The second model moves much closer to Flutter. Both can provide declarative interfaces, shared business logic, custom rendering, and a large percentage of common code.
Compose Multiplatform has a natural path for teams already using Kotlin and Jetpack Compose. Flutter has a different advantage: its rendering, navigation, package ecosystem, testing model, layout system, DevTools, and developer workflow were designed as one integrated stack from the beginning.
The practical question is not only whether a UI framework is officially stable. It is whether the exact UI, SDK, accessibility, navigation, text input, animation, and platform integration surface required by the product is mature enough for the team.
Framework stability is a project input, not a project conclusion.
Flutter’s position is still strong
KMP’s rise does not make Flutter irrelevant.
Flutter remains a clear choice when the organisational goal is for one product team to own a consistent experience across Android and iOS. It is especially strong when:
- the UI should look intentionally consistent across platforms;
- the product has a custom design system;
- the team is small;
- Android and iOS release together;
- delivery speed matters more than native UI ownership;
- the product may expand into desktop or an app-like web experience.
Flutter trades selective sharing for a more opinionated shared application model. That opinion is valuable when a predictable visual system and a single primary codebase are advantages.
Its cost is a commitment to Dart, Flutter’s rendering model, plugin quality, and platform abstractions. Teams still need native Android and iOS knowledge when the product requires deep platform integration.
For a Flutter team, the native layer is usually an exception. For a KMP team using native UI, the native layer is part of the primary architecture.
React Native is optimising for a different organisation
React Native is often treated as the older cross-platform option that KMP will eventually replace. That ignores its organisational advantage.
React Native is particularly strong when mobile is part of a broader React and TypeScript organisation:
- TypeScript talent is widely available;
- React knowledge transfers into mobile development;
- product teams can share patterns and packages with web teams;
- Expo provides a productive application and deployment ecosystem;
- native components and modules remain available when needed.
KMP asks, “How much native mobile logic can we share?”
React Native asks, “How much of our React and TypeScript organisation can extend into mobile?”
Those are not the same optimisation target. Choosing the architecture that fits an existing engineering organisation is a legitimate technical advantage.
The three technologies represent three operating models
The most useful comparison is not syntax, benchmark charts, or GitHub stars. It is the operating model each technology encourages.
| Technology | Default operating model | Primary advantage | Primary cost |
|---|---|---|---|
| KMP with native UI | Shared core with platform-owned interfaces | Native fidelity and selective adoption | Two UI implementations and cross-language boundaries |
| Compose Multiplatform | Kotlin-first shared application | Familiar path for Compose and Android teams | Younger cross-platform UI ecosystem |
| Flutter | Unified product team and shared UI stack | Consistency, productivity, and one primary codebase | Framework and Dart commitment |
| React Native | React/TypeScript organisation extended into mobile | Talent reuse and web ecosystem alignment | Dependency and native integration management |
| Fully native | Separate platform products | Maximum platform ownership | Duplication and coordination cost |
Declaring one universal winner usually means the analysis stopped too early.
When I would choose KMP
I would seriously consider KMP when an organisation already has native Android and iOS applications and wants to reduce logic drift without rewriting the product.
Strong candidates include:
- banking or financial calculation engines;
- offline synchronisation;
- authentication and token policy;
- experimentation frameworks;
- networking and persistence foundations;
- shared domain rules;
- SDKs consumed by multiple applications;
- products with platform-specific design requirements.
I would begin with one high-value module. The first module should have identical behaviour across platforms, limited platform dependencies, strong automated tests, measurable duplication, a known owner, and a rollback strategy.
I would not begin by moving every model, repository, view model, navigation rule, and screen into commonMain.
Maximum code sharing is not an architecture goal.
When I would choose Flutter or React Native
I would choose Flutter when the business needs one team to deliver Android and iOS together and the product benefits from a consistent custom interface. Startup products, operational apps, internal enterprise applications, marketplaces, and customer portals can all fit this model.
I would choose React Native when the organisation is already deeply invested in React and TypeScript, especially when mobile shares packages, schemas, validation, telemetry, or tooling with web applications.
These decisions are not admissions that one technology is universally better. They are choices about which operating model reduces the most risk for the specific team.
A safer way to evaluate KMP
Teams interested in KMP should not start by asking whether they can build the whole application with it. Start with five questions.
1. Which duplicated behaviour is expensive today?
Identify actual drift, repeated fixes, inconsistent tests, or duplicated business rules. Do not introduce a shared platform to solve hypothetical duplication.
2. Which platform must remain in control?
Payments, notifications, background tasks, maps, camera, Bluetooth, widgets, accessibility, and platform-specific design may need explicit native ownership. Define these boundaries early.
3. Who owns the shared code?
A shared module without shared ownership becomes another platform dependency. Decide whether ownership belongs to a mobile platform team, a feature team, or a dedicated shared-foundation team.
4. How will the iOS team evaluate the result?
Include Swift API quality, debugging, crash reports, binary size, startup time, build pipeline, testing, and release independence. The Android experience alone is not a valid KMP evaluation.
5. What is the exit path?
A pilot should be replaceable. A technology decision becomes safer when the team is allowed to prove it wrong.
Is Kotlin Multiplatform the future?
Yes, but not in the simplistic way technology headlines suggest.
Kotlin Multiplatform is likely to become an important part of mobile development because it makes cross-platform adoption less binary. Teams no longer need to choose only between two completely separate native applications and one framework owning the entire product.
KMP creates a third path:
- share the algorithm but keep the screens native;
- share the data layer but preserve platform SDKs;
- share presentation state while rendering it differently;
- use Compose Multiplatform for an internal tool but SwiftUI for the consumer app;
- move one library first and decide later whether the boundary should expand.
That flexibility is real. The hype begins when flexibility is confused with simplicity.
KMP still introduces new build pipelines, ownership questions, Swift interoperability decisions, library constraints, debugging differences, and platform-specific testing. Compose Multiplatform being stable does not guarantee that every complex iOS experience should immediately move to shared UI.
Flutter remains highly relevant for unified product teams and consistent interfaces. React Native remains highly relevant for React and TypeScript organisations. Native development remains relevant wherever platform capability is the product.
Kotlin Multiplatform does not need to kill any of them to succeed.
Its larger contribution may be changing what teams expect from cross-platform architecture.
The future of mobile development may not be “write once, run everywhere.” It may be:
Write shared code where inconsistency is expensive. Keep native ownership where platform differences create value.
That is less exciting than announcing a framework winner. It is also much closer to how production software is actually built.
