NK

Search

Search pages, posts, and components

All posts
Mobile9 min read

Flutter vs React Native vs SwiftUI vs Kotlin: Which Should You Pick?

Four ways to build a mobile app, compared on what actually decides it - rendering model, team, platform fidelity, and what each one costs you later.

flutterreact-nativeswiftuikotlinmobile

Every mobile framework comparison collapses into a list of bullet points that could describe any of them: fast, modern, great developer experience, strong community. All four of these are good enough to ship a serious product, which means the bullet points cannot be what decides it.

What decides it is a small number of structural differences - who draws the pixels, what you can share, and who you can hire - and those differences point at different answers depending on the app and the team, not at a winner.

This is the comparison I actually run through when someone asks. It covers what each one is, the four questions that settle most decisions, and where each choice hurts a year in.

What each one actually is

They are not four instances of the same thing, and half the confusion comes from treating them as if they were.

Flutter draws everything itself

Flutter ships its own rendering engine. A Button is not a UIButton - it is pixels Flutter paints. One Dart codebase targets iOS, Android, web, desktop, and embedded.

That buys pixel-identical output everywhere and complete design freedom, and it costs you platform behaviour: text selection, accessibility, and IME handling are Flutter's reimplementations rather than the OS's.

React Native uses the platform's own views

React Native runs your logic in JavaScript and maps components onto real native views - <Text> becomes a UITextView. You write React, and the platform draws.

That buys native feel and platform behaviour for free, and it costs you consistency: two platforms with really different components underneath, which you will meet the first time a list scrolls differently on each.

SwiftUI and Jetpack Compose are the native answers

SwiftUI (Apple) and Jetpack Compose (Android) are declarative UI frameworks for one platform each. Same mental model as the other two - describe the UI as a function of state - with no abstraction layer.

Pairing them means two codebases. Which is the honest framing of "native": not one better thing, but two of everything.

Kotlin Multiplatform shares logic, not UI

KMP is the odd one out and the most misunderstood. It compiles Kotlin for both platforms so you can share business logic - networking, models, validation, persistence - while writing the UI natively in SwiftUI and Compose.

So it is not really a competitor to Flutter; it is a different bet. Flutter says share the UI too. KMP says the UI is exactly the part worth writing twice.

The four questions that settle it

Feature tables do not decide this. These questions do.

Should the app look like the platform, or like your brand?

This is the single most useful question, and it splits the field cleanly.

If the answer is platform - the app should feel like it came with the phone, follow every OS convention, adopt new system styling automatically - then React Native, SwiftUI, or Compose. Flutter can imitate the platform, and it will always be imitation, chasing changes rather than inheriting them.

If the answer is brand - a strong custom design system that should look identical on every device - then Flutter is the strongest option in this list. It does not fight you, because there is no platform styling to override, and your designer's mockup is achievable rather than approximate.

What does your team already know?

Uncomfortable, and usually decisive.

A React team will be productive in React Native within a week. A team of JavaScript developers will be slower in Flutter for a month while Dart and the widget model land.

An iOS team that knows Swift should think very hard before choosing anything else - their existing expertise is worth more than any framework advantage on this list.

And "we will hire for it" is a plan with a cost: Flutter and React Native both have deep talent pools, KMP's is much shallower, and dual native teams are roughly twice the hiring problem.

How much of the app is UI?

An app that is mostly screens over an API - a marketplace, a booking flow, a dashboard - is mostly UI, and sharing that UI is where the savings are. Flutter and React Native shine.

An app that is mostly logic - a sync engine, offline rules, encryption, a domain model - has its complexity below the UI. That is exactly the case KMP was designed for: share the hard part, write two thin UIs over it.

How deep do you need to reach into the platform?

Every framework can reach native code, but the cost differs. Flutter uses platform channels or FFI; React Native uses native modules or its newer JSI bridge; SwiftUI and Compose are already there.

If your app leans hard on new OS features - a watch app, widgets, a rewritten camera pipeline, App Intents - native gets those on day one, and everything else waits for a plugin or you write the bridge yourself.

The comparison, without the marketing

FlutterReact NativeSwiftUI + ComposeKotlin Multiplatform
LanguageDartTypeScriptSwift + KotlinKotlin (+ native UI)
RenderingOwn engine, draws every pixelReal platform viewsPlatform-nativePlatform-native
What is sharedUI and logicUI and logicNothingLogic only
Platform fidelityImitatedInheritedNativeNative
Design consistencyIdentical everywhereDiverges by platformDiverges by designDiverges by design
CodebasesOneOneTwoOne shared + two UIs
Hiring poolLargeVery largeLarge but splitSmall
New OS featuresWait for pluginWait for moduleImmediateImmediate
Binary size floorHighest (ships engine)ModerateLowestLowest
Best fitBrand-led UI, many targetsReact teams, platform feelOne platform, or fidelity above allLogic-heavy apps, native UI

Two rows deserve caveats, because they get quoted out of context.

Performance is not in this table, deliberately. All four are fast enough that your bottleneck will be images, list rendering, or an unindexed query long before it is the framework. Anyone choosing between these on benchmark numbers is optimising the wrong variable.

"Codebases: one" is doing quiet work. One codebase is not one platform - you still test on both, still hit platform-specific bugs, still maintain two store listings and two release processes. Cross-platform reduces the code, not the surface area.

Where each one hurts a year in

The interesting information is not what they are good at.

Flutter hurts on platform integration and polish at the edges. Text selection handles, scroll physics, IME behaviour with some keyboards, and any brand-new OS feature. Also binary size: you ship an engine.

React Native hurts on the boundary. Anything crossing between JS and native frequently - animation driven by JS state, heavy lists, image-heavy scrolling - is where the architecture shows. The New Architecture improves this materially, and it does not eliminate it.

SwiftUI + Compose hurts on duplication. Every feature is specified once, built twice, tested twice, and drifts. Bugs get fixed on one platform and not the other. This is a real, recurring tax rather than a one-off cost.

Kotlin Multiplatform hurts on ecosystem and tooling. Fewer libraries, thinner answers when you search an error, and the Swift interop is workable rather than pleasant. You are earlier on the maturity curve than the other three.

Key takeaways

  • They are not four of the same thing. Flutter draws its own pixels, React Native uses platform views, SwiftUI/Compose are native, KMP shares only logic.
  • "Platform-like or brand-like?" splits the field faster than any feature comparison.
  • Your team's existing skills usually outweigh every framework advantage listed here.
  • UI-heavy apps favour shared UI (Flutter, React Native); logic-heavy apps favour shared logic (KMP).
  • Performance is not the deciding factor. All four are fast enough; your bottleneck will be elsewhere.
  • One codebase is not one platform. You still test, ship, and debug on both.
  • Each hurts somewhere specific a year in - platform polish, the JS boundary, duplication, or ecosystem maturity.

FAQ

Is Flutter dying because of layoffs at Google?

The team shrank; the project did not stop. Releases continue, Impeller shipped, and adoption outside Google is broad. It is a fair thing to weigh in a five-year bet, and it is not the crisis the headlines implied.

Is React Native still slow?

The old bridge deserved its reputation. The New Architecture - JSI, Fabric, TurboModules - removes the serialised bridge for most work, and the gap to native is now small enough that it rarely decides anything. Judge it on its current architecture, not on 2018 blog posts.

Can I use Kotlin Multiplatform with Compose everywhere?

Compose Multiplatform does target iOS, which turns KMP into a shared-UI option much closer to Flutter. It is younger and less proven on iOS than the rest of this list; promising, but not the same maturity.

What about Ionic, Capacitor, or web wrappers?

They are a legitimate choice for content-shaped apps where a web view is actually enough. For anything with heavy interaction, gestures, or animation, you will feel the ceiling early. That difference in ambition is why they are not in the table above.

Which one should a solo developer pick?

Whichever you can ship with. If you know React, React Native. If you want one codebase across mobile, web, and desktop, Flutter. If you only care about iPhone, SwiftUI and enjoy the simplicity of not abstracting anything.

Does choosing wrong doom the project?

Rarely. Products fail from unclear scope and slow iteration far more often than from framework choice. What a wrong choice costs you is speed - and a rewrite is usually cheaper than teams expect, provided your business logic was not tangled into the UI.

Conclusion

There is no winner here, which is unsatisfying and true. Flutter is the best answer for a brand-led UI across many targets. React Native is the best answer for a React team that wants platform feel. SwiftUI and Compose are the best answer when fidelity matters more than duplication. KMP is the best answer when the hard part of your app is not the UI at all.

Answer the four questions honestly - platform or brand, what the team knows, how much is UI, how deep you reach - and usually one option is clearly ahead. If two still tie, pick the one your team will enjoy more, and spend the saved deliberation on the product instead.

Read more

If Flutter is where you land, the follow-ups are How to Build Your First Flutter App to get moving, then How to Structure a Scalable Flutter Application before the codebase grows. For what "Flutter draws its own pixels" really means, see Flutter Is Not Just a UI Framework.