跪拜 Guibai
← All articles
Android · Frontend

KMP Shares Logic, React Native Shares UI — and That Changes Everything

By 黄林晴 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

The choice between KMP and RN is really a choice about which complexity you centralize and which you leave to platform specialists. Picking the wrong boundary for your team's structure and existing codebase turns a code-sharing win into a maintenance drag.

Summary

Kotlin Multiplatform and React Native represent two fundamentally different bets on where to share code. KMP leaves Android and iOS UIs alone — Compose, SwiftUI, XML — and moves domain logic, data access, and networking into a `commonMain` module that exposes UseCases, Repositories, and models. RN, by contrast, makes the UI the shared layer, with JS/TS components driving rendering on both platforms and native modules handling device capabilities.

This difference reshapes team structure and migration cost. KMP fits shops where Android and iOS engineers already own their platform UIs and want to eliminate duplicate business logic without rewriting screens. The shared module never imports `Context`, `ViewModel`, or SwiftUI; it returns `Result` or domain errors and lets each platform decide how to display a toast. RN suits teams that want one codebase for the interface and can maintain the JS-to-native bridge long-term.

Neither approach is free. KMP demands clean boundaries — code that reads `Build.VERSION` or passes `Context` must be refactored out — and iOS still carries the engineering burden of consuming Kotlin/Native frameworks, coroutines, and Flow from Swift. RN carries its own upgrade and compatibility tax. For a product with existing native clients and divergent UIs, sharing the business layer first is often the lower-risk move.

Takeaways
KMP shares domain logic, data access, and networking in `commonMain` while keeping native UIs separate; RN shares the UI layer in JS/TS and bridges to native modules for device capabilities.
A KMP shared module exposes UseCases, Repositories, and models without importing Android `Context`, `ViewModel`, or iOS SwiftUI — each platform owns its own presentation.
Migrating an existing Kotlin Android project to KMP means moving pure Kotlin code to `commonMain`, defining interfaces for storage and platform services, and providing `androidMain`/`iosMain` implementations.
KMP's compilation boundary is enforced by build configuration: `commonMain` depends only on cross-platform libraries like Ktor and kotlinx.serialization, not on platform SDKs.
RN's UI sharing reduces duplicate screen code but introduces a JS-to-native bridge that must be maintained for complex animations, system pages, widgets, and platform SDKs.
KMP fits teams where Android and iOS engineers own their respective UIs; RN fits teams that want one UI codebase and can maintain JS/TS alongside native modules.
Shared code in KMP should never depend on the page layer — `commonMain` returns `Result` or domain errors, and each platform decides how to present feedback like toasts.
Both approaches carry ongoing platform costs: KMP requires Xcode integration and Kotlin/Native artifact management; RN requires version upgrades and native dependency compatibility work.
Conclusions

The article frames KMP and RN not as competitors in the same category but as solutions to different problems — one shrinks business-logic duplication, the other shrinks UI duplication — and the real decision is which layer your team can afford to share.

KMP's insistence on keeping UI on the platform side means it slots into existing native projects with less disruption than RN, which demands a more fundamental renegotiation of who owns the screen.

The migration advice is unusually pragmatic: start by moving pure Kotlin code and let compilation errors surface the unclean boundaries, rather than attempting a big-bang refactor.

Concepts & terms
Kotlin Multiplatform (KMP)
A Kotlin technology that compiles shared business logic, data access, and networking code to Android, iOS, and other targets while leaving platform-specific UI code separate.
commonMain
The shared source set in a KMP project where platform-agnostic code lives — models, UseCases, Repositories, and API interfaces — compiled for all targets.
Compose Multiplatform
A JetBrains framework extending Jetpack Compose to desktop and iOS, allowing shared UI code across platforms, though using it is a separate decision from sharing domain logic in KMP.
Kotlin/Native
A Kotlin compiler backend that produces native binaries for iOS (and other platforms) without a JVM, enabling shared Kotlin code to run as an iOS framework consumed by Swift.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗