All writing

Kotlin Multiplatform vs Flutter vs React Native for native app teams

Kotlin Multiplatform vs Flutter vs React Native: if you already ship native iOS and Android apps, KMP shares code without a rewrite. When the others win.

If you already ship a native Android app and a native iOS app, Kotlin Multiplatform is usually the better fit of the three, because it is the only one that starts from the code you have: a shared Kotlin module goes in beside both apps, and nothing about either UI has to change on day one. Flutter and React Native can be added to an existing app too, but each brings a new language and a new UI layer with it. If you have no app yet and want one UI drawn the same way everywhere, the answer changes, and this post says when.

A bias, stated up front: the studio's Kotlin Multiplatform client work is built on that premise, shared modules landing alongside existing native code. So Flutter and React Native are described from their own documentation, not JetBrains', and every status carries its date, checked on 3 October 2026.

The question that decides it

For a team with apps in the stores, three questions settle it:

  1. Do you already have native apps and native engineers? Then what matters is how much of that each option keeps.
  2. What does the team already write? Kotlin, Swift, Dart, or JavaScript and TypeScript.
  3. How much UI do you actually want to share? None, some screens, or all of it.

Google's own guidance draws the line along the third question. Its post of 14 May 2024, Making development across platforms easier for developers, says Kotlin Multiplatform "helps reduce code duplication and makes maintenance easier for shared business logic, and you will continue to build your UI using platform specific APIs", and that "Flutter is Google's recommended SDK for when you want to share business logic and UI code across all platforms". It predates Compose Multiplatform for iOS going Stable, so KMP now has a shared-UI option too; the split on intent holds.

What each one shares, in its own words

Kotlin MultiplatformFlutterReact Native
LanguageKotlinDartJavaScript, TypeScript
What is shared"from 1% to 100%", logic and optionally UIlogic and UIlogic and UI components
How the UI is drawnnative UI, or Compose Multiplatform drawn through SkiaFlutter's own widgets, rendered by Impellerplatform views created from React components
Calling platform codedirect, from Kotlinplatform channels or FFInative modules over JSI
Into an existing appas a library (an XCFramework for iOS)as a module ("add-to-app")as a view or user flow

Kotlin Multiplatform. JetBrains' comparison with Flutter (modified 21 July 2026) puts it as "share whichever part of your codebase you want to, including business logic and/or UI, from 1% to 100%." Shared UI is Compose Multiplatform, which the same comparison says renders using the Skia engine.

Flutter. Flutter's architectural overview (updated 29 September 2026, reflecting Flutter 3.47) is explicit that "Flutter has its own implementations of each UI control, rather than deferring to those provided by the system". Its rendering engine, Impeller, "is shipped along with the application". For release, "Flutter apps are compiled directly to machine code". Kotlin and Swift code is reached through platform channels, which serialise messages between the two sides.

React Native. React Native's Core Components and Native Components page says: "At runtime, React Native creates the corresponding Android and iOS views for those components. Because React Native components are backed by the same views as Android and iOS, React Native apps look, feel, and perform like any other apps." Since 0.76 (23 October 2024), JavaScript and native code talk synchronously through JSI rather than an asynchronous bridge, and 0.82 (8 October 2025) was "the first React Native that runs entirely on the New Architecture".

Language, and the team you already have

This is where the comparison is least balanced. Google announced at I/O 2019 that Android development would be increasingly Kotlin-first, so a current Android team already writes the language Kotlin Multiplatform uses, in the IDE it already has. The shared module is ordinary Kotlin, and the Android app consumes it like any other Gradle module.

Flutter asks both platform teams to learn Dart and Flutter's widget model. React Native asks them to learn React, JavaScript or TypeScript, and the Node toolchain: 0.87 (11 August 2026) raised the minimums to Node.js 22, Android Gradle Plugin 9 and Kotlin 2.0+. Equally, if the people who will maintain the shared code are web developers who already write React, React Native is the option that starts from their skills, the way KMP starts from an Android team's.

The iOS team is the cost KMP does not hide. The shared code is Kotlin, so somebody on the iOS side reads Kotlin, or at least its API from Swift. Today that API reaches Swift through an Objective-C header. Swift export, which maps Kotlin straight to Swift, "is currently in Alpha and still incomplete, so breaking changes are expected" (doc modified 28 August 2026). Is Kotlin Multiplatform production-ready? has every status in that chain with its date.

Native look, and what happens when iOS changes

What happens when Apple restyles the system controls?

  • Flutter draws everything itself, by design. Its overview counts this as a benefit: the app "looks and feels the same on all versions of the OS, even if the OS changed the implementations of its controls." To follow a new iOS look, you update the widgets. Since Flutter 3.47 (12 August 2026), Material and Cupertino ship as standalone packages, material_ui and cupertino_ui, so you can "use the latest Cupertino and Material widget styles without being forced to upgrade your entire Flutter SDK version."
  • React Native uses the platform's own views, so a restyled system control arrives with the OS.
  • Compose Multiplatform behaves like Flutter. The KMP FAQ (modified 1 October 2026) answers it directly: "Your UI will stay the same after the OS updates because all of the components are drawn on a canvas. If you embed native iOS components into your screen, updates may affect their appearance."
  • KMP with native UI behaves like any native app, because it is one. The SwiftUI screens stay SwiftUI.

Compose Multiplatform is an option per screen, not a requirement: SwiftUI integration runs both ways, embedding Compose in a SwiftUI app or SwiftUI inside a Compose screen. It has been Stable on iOS since Compose Multiplatform 1.8.0 on 6 May 2025. JetBrains states that it adds "only ~9 MB" to an iOS app compared with SwiftUI. That is JetBrains' measurement, and it applies to shared UI, not to a logic-only module.

Adding to an app you already ship

All three can be added to an existing app. What differs is what you add, and what the rest of the project has to change to take it.

Flutter calls it add-to-app (updated 31 July 2026): a Flutter module renders part of the app "while the rest can be rendered using existing technology", either built automatically by Gradle or Xcode or packaged as an Android Archive for Android and a Swift package for iOS. The same page notes it "can also be used to run shared non-UI logic". Its limits are worth reading before you plan on several features: "Packing multiple Flutter libraries into an application isn't supported", and each Flutter instance on mobile is a separate Dart program.

React Native says its integration guide "works well for adding a single view or user flow to existing native applications". On iOS the guide's first step is to "move your existing iOS project to the /ios subfolder" of a new React Native project, then add React Native through the Podfile and host it in an RCTRootView. Swift Package Manager support arrived in 0.87 as experimental. Either way, the result is a JavaScript project at the root of the repository, with the iOS app beneath it.

Kotlin Multiplatform inverts the arrangement. Nothing moves: the shared module is a dependency of both apps. Android pulls it in through Gradle. For iOS, JetBrains' SPM export guide (modified 21 July 2026) builds an XCFramework, uploads it as a zip, and keeps the Package.swift "in a separate Git repository", so the iOS team adds a Swift package and carries on in Xcode; this walkthrough covers what changes on their side. The first module can be as small as one piece of logic both apps currently duplicate: a network client, validation rules, a pricing calculation.

From the studio: This is the step our Kotlin Multiplatform work is built around: a shared module lands in your repository beside both native apps, and Compose Multiplatform screens follow only where you choose them. Send a short description of the app, and the reply comes from the person who would write the module.

Accessibility on iOS

Anything that draws its own pixels has to rebuild what the platform gives native views for free.

React Native's views are platform views, and its accessibility APIs are described as complementary to VoiceOver and TalkBack. For Compose Multiplatform, the iOS accessibility doc (modified 22 July 2025) maps Compose semantics to native iOS accessibility objects, supports VoiceOver, Full Keyboard Access and AssistiveTouch, and maps testTag to accessibilityIdentifier so XCTest can run accessibility audits against it. One gap: Material 3's colour scheme has no high-contrast variant out of the box, so you define one. Flutter's accessibility guide asks you to test with TalkBack and VoiceOver, and where Flutter hosts a native control in a platform view, its overview lists "creating an analog of the accessibility tree" among the synchronisation work, which carries "a certain amount of overhead".

Screens that stay native keep the accessibility they have now.

When we would tell you to pick Flutter or React Native

KMP is not the answer to every version of this question.

  • No apps yet, one design across platforms, no native engineers. Flutter. You want every pixel identical on Android and iOS, the team is starting from scratch either way, and Google recommends it for exactly the case of sharing UI and logic everywhere.
  • The maintainers are React developers. React Native. A web team that already writes React and TypeScript keeps its language and its component model, and gets platform views. For a new app the React Native docs recommend a framework such as Expo rather than starting bare.
  • Your existing apps are being replaced anyway. If both native apps are scheduled for a rewrite, the argument for keeping native code weakens, and the choice comes down to languages and UI again.

A decision table by what you already have

What the team hasStart with
Native Android and iOS apps, Kotlin on Android, UI to stay nativeKotlin Multiplatform for shared logic
The same, plus screens that are identical on both platformsKMP, then Compose Multiplatform for those screens
An Android app in Jetpack Compose, no iOS app yetKMP with Compose Multiplatform
Kotlin on Android, an iOS team that wants to stay in SwiftUI and XcodeKMP, shipped to iOS as a Swift package
No apps, no native engineers, one design everywhereFlutter
A React web team maintaining the mobile appsReact Native

Status of each, dated

ItemStatusDateSource
Kotlin Multiplatform core (Android, iOS)Stablestability page modified 10 Sep 2025JetBrains
Compose Multiplatform for iOSStablesince 1.8.0, 6 May 2025JetBrains blog
Swift exportAlphadoc modified 28 Aug 2026Kotlin docs
Flutter3.47released 12 Aug 2026Flutter blog
React Native New Architecturethe only architecturesince 0.82, 8 Oct 2025React Native blog
React Native0.87.1released 26 Aug 2026GitHub

Statuses move, and Swift export is the one most likely to change next. If anything here disagrees with the page it links to, the linked page is correct.

If you have native apps in the stores and want to know what a first shared module would look like in yours, write down the logic both apps duplicate today, then send that list and a short description of the apps through the contact form.

All writingNextWhy your Logitech keyboard types the wrong keys after a KVM switch