Short answer: choose Flutter when one team needs a highly consistent custom interface across iOS and Android; choose React Native when your organisation already has strong React and TypeScript capability and the required native libraries are mature; choose native Swift and Kotlin when the product depends heavily on platform-specific hardware, background processing, the newest operating-system features, or uncompromised platform behaviour. None is automatically cheapest or fastest. The right choice is the one that leaves the least expensive complexity in your specific product.
I would not approve a mobile stack from a feature checklist or a framework popularity chart. I would first test the app’s hardest technical path, the team that must maintain it, and the native dependencies that cannot fail. This guide gives business owners and product leaders a practical way to make that decision.
Flutter vs React Native vs native: the decision in one table
| Decision factor | Flutter | React Native | Native Swift and Kotlin |
|---|---|---|---|
| Primary model | Shared Dart application and Flutter-rendered UI | Shared JavaScript or TypeScript application connected to native platform capabilities | Separate first-party iOS and Android applications |
| Best organisational fit | One mobile team; strong need for visual consistency | React/TypeScript organisation; mobile team can handle native edges | Platform-specialist teams or one-platform product |
| Platform look and behaviour | Consistent by design; must deliberately adapt where platforms differ | Can share most product logic while preserving platform-specific files and modules | Direct access to platform UI conventions and APIs |
| Unusual hardware or new OS APIs | Possible through plugins or platform channels; validate early | Possible through libraries or native modules; validate compatibility early | Direct first-party path |
| Maintenance shape | One main codebase plus native integration code | One main codebase plus native modules/configuration | Two codebases, teams and release tracks |
| Main procurement risk | Assuming every plugin is production-ready for your use case | Assuming web React experience removes the need for mobile/native expertise | Funding two platforms without strong parity governance |
This is a starting point, not a verdict. A reliable decision needs product evidence.
What each option actually means
Flutter
Flutter is a Google-supported toolkit built around Dart. Its architecture differs from native UI toolkits: Flutter’s engine rasterises the application’s scenes, while the framework supplies its own widget system. The official Flutter architectural overview explains that Dart application code is compiled to native code for mobile and that the engine uses Impeller for rendering.
That model gives a team strong control over cross-platform visual consistency. It does not remove platform work. Flutter’s own platform-channel documentation describes how apps call Kotlin, Java, Swift or Objective-C code when a platform API is not adequately exposed through Dart or an existing plugin.
React Native
React Native lets teams build Android and iOS applications with React and JavaScript or TypeScript while integrating with native components and APIs. Its modern architecture includes Fabric rendering and Turbo Native Modules. React Native 0.82 made the New Architecture the only runtime option, and subsequent releases have continued removing legacy code. The practical procurement point is simple: current library compatibility matters more than advice written for the old asynchronous-bridge architecture.
The official New Architecture documentation explains capabilities such as synchronous layout access and improved scheduling. React Native also provides code generation for native modules, but teams still need Swift/Kotlin or Objective-C/Java competence when a requirement crosses the framework boundary.
Native Swift and Kotlin
Native development normally means an iOS app built with Swift and Apple frameworks, plus an Android app built with Kotlin and Android frameworks. Apple’s SwiftUI and Google’s Jetpack Compose are both declarative UI toolkits, so “native” no longer means accepting slow, old-style UI development.
The advantage is direct access to platform capabilities, conventions and release tooling. The trade-off is organisational: two applications still need implementation, testing, release management and parity decisions, even when they share API contracts and product design.
1. Start with the product’s hardest requirement
Do not evaluate frameworks against the easiest screens. Login, lists, forms and standard API calls are not where a stack decision normally fails. Find the requirement with the most uncertainty or the highest business consequence.
Typical stress points include:
- continuous or background location;
- Bluetooth, NFC, external scanners or specialist sensors;
- camera pipelines, media processing or augmented reality;
- large offline datasets and two-way synchronisation;
- complex gestures, animation or high-frequency visual updates;
- secure device credentials and enterprise identity;
- long-running uploads, downloads or background tasks; and
- a third-party native SDK central to revenue or operations.
Build a small proof of concept around that path before locking the commercial estimate. A successful prototype should run on representative physical devices and demonstrate the real SDK, permission, offline and failure behaviour—not a mocked happy path.
2. Decide whether platform parity or platform fidelity matters more
Flutter is attractive when the brand requires a controlled visual system that should remain highly consistent across platforms. React Native can also support a shared design system, while still allowing platform-specific implementations where necessary. Native development makes it easiest to adopt first-party platform components and interaction patterns independently.
Neither parity nor fidelity is always correct. A field-workforce app may benefit from near-identical training and workflows across company devices. A consumer product may benefit from behaving exactly as iOS and Android users expect on each platform. Write this preference into the product requirements instead of leaving it to individual developers.
3. Price the team you have, not the code reuse you imagine
Shared code can reduce duplicated implementation, but it does not make two operating systems identical. You still have two store submissions, signing arrangements, permission models, device populations and release risks.
React Native is often a sensible organisational fit when a mature React/TypeScript team can move into mobile with experienced mobile leadership. Flutter can be cleaner when you want one dedicated mobile team and are comfortable hiring for Dart. Native makes sense when you already have platform specialists, when one platform dominates, or when the product justifies dedicated teams.
Ask who will maintain the app in two or three years. A framework that is easy for the initial agency but difficult for your future team is not automatically economical.
4. Audit plugins, SDKs and native dependencies before choosing
Create a dependency register before approving the stack. Include payments, maps, identity, analytics, crash reporting, push notifications, camera, Bluetooth, biometrics, deep links and any industry-specific SDK.
For each dependency, record:
- official iOS and Android SDK support;
- the Flutter plugin or React Native library proposed;
- maintenance activity and compatibility with the selected framework architecture;
- platform-version and device limitations;
- whether your team can repair or replace the wrapper; and
- the fallback if the wrapper lags behind a vendor or OS update.
For React Native, use the ecosystem’s compatibility information as evidence, not just package popularity. For Flutter, inspect the package’s supported platforms and native implementation. If a critical dependency is uncertain, test it on both platforms before signing the build contract.
5. Replace performance opinions with a workload test
There is no useful answer to “which framework is fastest?” without a workload, device, build mode and measurement boundary. A recent cross-platform study comparing native, Flutter, React Native and Kotlin Multiplatform found that results varied by operation and quality attribute rather than producing one universal winner. That is the right way to interpret framework performance.
Define the product metrics that users will feel:
- cold and warm startup;
- time to interactive;
- frame consistency during the hardest animation or list;
- memory use with a realistic dataset;
- battery impact during background work;
- offline query and synchronisation time; and
- crash and application-not-responding behaviour.
Measure release or profile builds on representative low, middle and high devices. Flutter’s documentation explicitly warns that debug mode is not representative for performance testing. Google’s Android vitals also reinforces that production quality includes stability, performance, battery and permission behaviour—not only smooth demo screens.
6. Treat accessibility and device testing as stack requirements
Every option can produce an accessible app, and every option can produce a poor one. The quote should cover screen-reader labels, focus order, dynamic text, contrast, touch targets, keyboard behaviour where relevant, reduced motion and accessible errors.
Cross-platform automation does not replace physical testing with VoiceOver and TalkBack. Native components can provide useful platform behaviour by default, but custom components still need verification. Flutter’s custom-rendered widget model and React Native’s abstraction layer both require deliberate testing of semantics and third-party components.
7. Compare maintenance and upgrade paths
The stack decision continues after launch. Apple and Google release operating-system, SDK, privacy and store-policy changes. Flutter and React Native add another upgrade layer, plus plugin or library compatibility. Native apps avoid the cross-platform framework layer but still have two platform toolchains and codebases.
Ask each vendor for an upgrade policy covering:
- framework and language releases;
- Xcode, Android Gradle Plugin and SDK changes;
- third-party library replacements;
- deprecated platform APIs;
- supported OS versions and device testing;
- security patches and dependency scanning; and
- ownership of store-policy remediation.
Yesterday’s guide on how to compare mobile app development quotes gives you the wider scope, QA, ownership and support checks to apply after the stack decision.
When Flutter is the strongest choice
Flutter is usually a strong candidate when:
- one mobile team must ship both platforms;
- the interface is highly branded or visually custom;
- consistent behaviour matters more than using first-party UI components everywhere;
- critical native capabilities have been validated through maintained plugins or a small amount of platform code; and
- the organisation is comfortable owning Dart and the Flutter upgrade cycle.
Do not choose it merely because a proposal promises “one codebase.” Confirm how much platform-specific work remains and who can support it.
When React Native is the strongest choice
React Native is usually a strong candidate when:
- the organisation already has strong React and TypeScript capability;
- shared product patterns, tooling or people across web and mobile have real value;
- required native libraries support the New Architecture;
- the team includes genuine iOS and Android competence for native edges; and
- the product benefits from a large JavaScript ecosystem without pretending web and mobile code are identical.
Do not choose it solely to redeploy web developers. Mobile lifecycle, permissions, performance, accessibility and store release work remain specialised.
When native development is the strongest choice
Native Swift and Kotlin are usually strongest when:
- only one platform is required;
- the app depends on new or advanced platform APIs immediately;
- hardware, media, background execution or platform integration is central to the product;
- the experience must follow each platform deeply rather than remain visually identical;
- the organisation can fund and govern two platform teams; or
- measured performance constraints justify direct platform control.
Native is not automatically excessive, just as cross-platform is not automatically economical. Complexity moves; it does not disappear.
A practical selection scorecard
| Criterion | Weight | Evidence required |
|---|---|---|
| Critical device and OS capabilities | 20% | Physical-device proof of concept |
| Team and hiring fit | 15% | Named maintainers and skills-gap plan |
| SDK and dependency confidence | 15% | Dependency register and fallback plan |
| UX parity versus platform fidelity | 10% | Approved design principles and sample flows |
| Measured performance | 15% | Benchmark of the hardest workload |
| Accessibility and QA | 10% | Device matrix and acceptance criteria |
| Upgrade and maintenance path | 10% | Supported-version and dependency policy |
| Source ownership and exit path | 5% | Repository, build, documentation and handover terms |
Score each option from 0 to 3: missing, assumed, evidenced, or evidenced on your product. Change the weights where your risk differs. A field app may weight offline and hardware much more heavily; a content app may emphasise team efficiency and design consistency.
What I would require before approving the stack
- A written architecture decision record explaining why this option fits the product and team.
- A dependency register for every business-critical SDK and native capability.
- A proof of concept for the hardest workflow on real iOS and Android devices.
- A performance test using realistic data and a release/profile build.
- An accessibility check with VoiceOver and TalkBack.
- A two-year ownership view covering upgrades, monitoring and library replacement.
- A handover plan proving another competent team can build and release the app.
If a vendor will not provide this evidence, the framework name is not your biggest risk.
Frequently asked questions
Is Flutter better than React Native in 2026?
Not in the abstract. Flutter gives strong visual consistency and an integrated Dart toolkit. React Native often fits organisations with mature React and TypeScript capability. Validate critical SDKs, native features, performance and maintenance before deciding.
Is React Native still using the old bridge?
Current React Native releases use the New Architecture. React Native 0.82 made it the only runtime option, replacing the old architecture as a basis for new decisions. Existing apps and libraries still need compatibility review during upgrades.
Does cross-platform mean one hundred percent shared code?
No. Platform permissions, signing, store configuration, device behaviour and some SDK integrations remain platform-specific. A good proposal states the expected native code and testing rather than promising complete reuse.
Are native apps always faster?
Native provides direct platform control, but a useful performance decision requires a defined workload and physical-device measurements. Many business apps can perform well in any of the three approaches when engineered correctly.
Which option is cheapest to maintain?
It depends on team capability, platform scope and native dependency load. One shared codebase can reduce duplicated work, while a poorly supported plugin or repeated framework upgrade problems can remove that advantage. Compare total ownership, not initial screen-building effort.
Can Flutter or React Native access Bluetooth, camera and biometrics?
Yes, through maintained packages, libraries or custom platform code. The important question is whether the exact hardware, background mode and SDK version your product needs are supported and tested.
Should we build a proof of concept before choosing?
Yes when a critical feature, dependency or performance requirement is uncertain. Keep it narrow: test the hardest technical path on representative devices and define a pass/fail result before commissioning the full build.
Choose the stack from evidence, not preference
Flutter, React Native and native development are all credible production choices. The expensive mistake is selecting one before the team has exposed product-specific complexity. If you are planning a new customer, workforce or platform-connected app, review my mobile app development approach. To pressure-test the architecture and scope before committing, book a 15-minute conversation.