Native mobile apps: React Native vs Flutter (Dart) vs Kotlin
There is no universal “best” choice. The right stack depends on who builds the app, which platforms you ship, how much native polish you need, and how your team already works. This page explains each path in plain language so you can compare process (how you build and ship) and tradeoffs (what you gain and give up).
1. What each option actually is
| Name | What it is | Typical languages |
|---|---|---|
| React Native | One JavaScript/TypeScript codebase drives real native UI components on iOS and Android (via a bridge into the native toolkits). | JavaScript, TypeScript |
| Flutter | Apps are written in Dart. Flutter draws its own UI using a high-performance engine (Skia/Impeller); it is not wrapping the platform’s stock buttons by default. | Dart |
| Kotlin (Android-first) | Kotlin is the modern native language for Android. You use Android SDK components directly. For iOS, you normally use Swift (or shared code via Kotlin Multiplatform, see below). | Kotlin (+ Swift for iOS if you go fully native per platform) |
Important clarification: People often say “Dart” when they mean Flutter. Dart without Flutter is uncommon for mobile; for app decisions, treat Dart + Flutter as one option.
2. The “better” process depends on your goal
You want one team, iOS + Android, fastest feature velocity
- Strong options: React Native or Flutter.
- Why: One product codebase, one design system to maintain, coordinated releases.
React Native fits especially well when the org is already strong in React and TypeScript (web and app code can share patterns, types, and sometimes libraries).
Flutter fits especially well when you want very consistent UI across platforms and a single strongly opinionated framework (widgets, animation, tooling).
You want maximum platform fidelity or deep integration with new OS APIs immediately
- Strong option: Native per platform — Kotlin + Android SDK on Android, Swift + UIKit/SwiftUI on iOS.
- Why: No bridge, no embedded engine; you follow Google’s and Apple’s recommended paths exactly. This matters for heavy media pipelines, complex accessibility edge cases, or products where last-mile performance and OS integration are the brand.
You are Android-only today
- Kotlin is the default professional choice for native Android.
- Cross-platform (React Native or Flutter) can still make sense if you know iOS or web variants are coming soon and you want to avoid a rewrite.
You want shared business logic, but native UIs on each OS
- Look at Kotlin Multiplatform (KMM) or similar patterns: shared Kotlin for networking, models, and domain logic; native UI on each side.
- This is a hybrid process: more setup than pure RN/Flutter, but less duplication than two completely separate codebases.
3. Side‑by‑side comparison (how practitioners actually decide)
| Dimension | React Native | Flutter (Dart) | Kotlin (native Android) |
|---|---|---|---|
| Primary win | Huge JS/TS ecosystem; easy hire if you already do web React | Consistent UI; strong built-in tooling; fast dev cycles for custom UIs | Best Android-native fit; official Google stack |
| iOS + Android from one codebase | Yes | Yes | Not by default — usually add Swift/iOS or KMM |
| How UI works | Native widgets bridged from JS | Custom rendering pipeline (pixel-level control) | Platform widgets directly |
| Performance | Great for most apps; hotspots may need native modules | Generally smooth; heavy scenes tuned like a game engine mindset | Excellent when written natively |
| Access to new OS features | Often needs community libs or native code soon after OS release | Same story: may wait for plugin/engine updates | Fastest on Android if you use APIs directly |
| Team skill match | Best if you already know React | Best if you like Flutter’s model | Best if you’re an Android specialist |
| Risk to own | Bridge + native-module edge cases | Engine + plugin ecosystem; larger app size considerations | Platform churn (Material, Gradle) managed by Android ecosystem |
None of these rows say “always win” — they say where each stack tends to shine.
4. The delivery process (build → test → ship) — what is similar, what differs
For React Native and Flutter, the release story is broadly similar:
- Develop with hot reload / fast refresh for day‑to‑day work.
- Build release binaries with platform toolchains (Xcode, Gradle).
- Sign and upload to Google Play and App Store.
- Run CI (tests, lint, typecheck) on every merge.
For native Kotlin Android, you skip the cross‑platform layer but follow the same Gradle → bundle/APK → Play pipeline. If you add iOS, you duplicate the Xcode → App Store track unless you use KMM or a second team.
What actually differs in practice:
- Cross‑platform (RN / Flutter): you coordinate one feature timeline, but you still debug two stores, two sets of store policies, and sometimes platform‑specific bugs.
- Native Kotlin + Swift: you coordinate two codebases (unless using KMM for shared layers), but each UI tracks its platform very naturally.
5. Decision guide (simple)
Use this as a starting map, not a law. Prototypes and spikes on real screens (lists, maps, camera, offline) beat abstract arguments.
6. Short honest summary
- React Native: Often the best process fit when your company is already a React/TypeScript shop and you want two mobile platforms without two full UI stacks.
- Flutter (Dart): Often the best UI consistency and framework coherence story for cross‑platform teams that commit to Flutter’s model.
- Kotlin: The right default for native Android. It is not a drop‑in substitute for cross‑platform unless you add iOS native or Kotlin Multiplatform — then you are choosing a different architecture on purpose.
If you document a choice for your team, record why (platforms, skills, offline needs, release cadence). That ages better than arguing about which name is “best.”
