Kotlin Multiplatform is no longer just an experiment worth watching. Kotlin Multiplatform itself is stable, and that changes the conversation from “Can we use it?” to “Where does sharing code actually create value?”
The biggest mistake I see in cross-platform discussions is treating code sharing as the goal.
It is not.
The goal is to reduce duplicated business logic without destroying the strengths of each platform.
What I like to share
The highest-value shared code is usually platform-independent logic:
- Domain entities.
- Use cases.
- Validation rules.
- API contracts.
- Authentication state.
- Repository interfaces.
- Networking.
- Serialization.
- Database access where the chosen library supports it well.
- Feature flags.
- Pricing and calculation rules.
- Date/time and formatting logic that has deterministic behavior.
This is the code that should behave identically on Android and iOS anyway.
Sharing it reduces drift.
What I am careful about sharing
UI is a product decision, not a religion.
Compose Multiplatform can be a strong option when a shared UI gives the team speed and consistency. But there are also products where native SwiftUI on iOS and Compose on Android provide better platform integration, design fidelity, or team ownership.
I prefer to decide based on:
- Product requirements.
- Native integrations.
- Team skills.
- UI complexity.
- Accessibility requirements.
- Long-term maintenance.
- Release independence.
The architecture should support the product, not the other way around.
Shared domain, native experience
One strategy I like is:
shared domain + shared data + native presentation
The shared module owns business behavior and data access. Android consumes it from Kotlin/Compose. iOS consumes it from Swift/SwiftUI.
This gives strong reuse where consistency matters while allowing each platform to feel native.
It also keeps the shared layer easier to test because it is not tied to a UI framework.
Where KMP becomes especially useful
KMP is attractive for products with meaningful business logic:
- Fintech.
- ERP.
- E-commerce.
- Booking.
- Healthcare workflows.
- Delivery.
- Offline-first applications.
- Applications with complex synchronization.
- Apps where Android and iOS must follow identical rules.
If the application is mostly a thin UI over simple CRUD endpoints, the value of a shared domain layer may be smaller.
Interop is part of the architecture
The iOS boundary deserves deliberate design.
A shared Kotlin API that looks elegant from Kotlin can be awkward from Swift if the exported types, errors, coroutines, or nullability are not designed for interoperability.
I treat the Swift-facing API as a public SDK:
- Keep it small.
- Use predictable types.
- Map internal errors to stable domain errors.
- Avoid leaking implementation details.
- Test from Swift, not only from Kotlin.
My practical rule
I do not ask “How much code can we share?”
I ask:
“What code must never behave differently between platforms?”
That code is the best candidate for KMP.
Everything else is a trade-off.
Kotlin Multiplatform gives teams a powerful middle ground between maintaining two completely separate products and forcing every layer into one cross-platform abstraction.
Used carefully, it can preserve native quality while eliminating duplicated business logic.
Official reference
- Kotlin component stability: https://kotlinlang.org/docs/components-stability.html