Every mobile project reaches this decision early, and it shapes the budget, the team and how easy the app is to change later. There is no universally right answer. There is usually a right answer for a particular app, and it comes from a few specific questions.
What “native” and “cross-platform” mean today
A native app is written separately for each platform in the platform’s own language and tools: Swift for iOS, Kotlin for Android. You get two codebases that each use the operating system directly.
A cross-platform app is written once and runs on both. The two common options are Flutter, which draws its own interface with the Dart language, and React Native, which uses JavaScript or TypeScript and renders native interface components. Both can still call native code when they need to, through plugins or small native modules.
The practical difference is less about what is possible and more about where the effort goes. Cross-platform saves effort on shared screens and logic. Native saves effort when the app spends much of its time talking to the operating system or hardware.
Where Flutter fits
Flutter is a good fit when:
- You want the same custom design on iOS and Android, pixel for pixel.
- Most of the app is screens, forms, lists, charts and data from a server.
- One team will maintain the app, and you would rather not keep two codebases in step.
The trade-off is that platform-specific features arrive through plugins. Popular features are well covered; unusual or very new ones may need native code written alongside the Flutter app.
Where React Native fits
React Native is a good fit when:
- Your company already works in JavaScript, TypeScript or React, on the web or elsewhere.
- The app shares business logic, or even developers, with a React web product.
- You want interface components that look and behave like each platform’s own.
The trade-off is similar to Flutter’s: deep platform or hardware work may still need native modules, and upgrades to the framework itself need planning.
When fully native is the right call
Native development earns its extra codebase when:
- The app’s core value depends on platform features — background processing, widgets, watch apps, advanced camera or audio work.
- The app talks to hardware over Bluetooth for long periods, or must keep working while the phone is locked.
- You need the newest OS features on the day they ship.
- You have, or plan to have, separate iOS and Android specialists.
Bluetooth, sensors and background work: what changes
Apps that connect to devices deserve their own question, because this is where the choice matters most. Pairing, reconnecting when a device drops out of range, streaming live data and sending firmware updates all lean on the platform’s Bluetooth stack and its rules for background work.
In our published connected sports-wearable case study, the iPhone and Apple Watch apps were built natively in Swift with Core Bluetooth, and the Android app natively in Java. The apps stream heart rate and breathing live from a sensor and deliver firmware updates to it. For that kind of product, native code was the straightforward path, because almost every important feature touched the Bluetooth stack.
Cross-platform apps can talk to Bluetooth devices too, through plugins. The question is how much of the app is Bluetooth: if it is one feature, a plugin may be fine; if it is the product, native is usually simpler to get right.
Performance, interface quality and OS updates
For most business apps, users will not feel a performance difference between a well-built Flutter, React Native or native app. Poor performance usually comes from how an app is built — too much work on the main thread, oversized images, chatty network calls — rather than from the framework.
What does differ is how each option absorbs change. Every year Apple and Google change their operating systems, and app stores raise their minimum requirements. Native apps adopt changes directly. Cross-platform apps also depend on the framework and its plugins keeping up, which they usually do, but which adds a step.
Team skills and long-term maintenance
An app lives for years. Before choosing, ask:
- Who will maintain it? If it is your own team later, choose what they know or can hire for.
- How many people will work on it? Two native codebases need either two specialists or one person who switches between them.
- How often will it change? Frequent changes across both platforms favour one shared codebase.
A decision checklist
- Write down the app’s riskiest feature. If it is hardware, background work or a platform feature, lean native.
- Write down who maintains the app in two years. Choose a technology they can work in.
- Check whether the app shares logic with a web product. If it does, React Native deserves a look.
- Check whether design must be identical on both platforms. If it must, Flutter deserves a look.
- If the answers point in different directions, build a small proof of the riskiest feature first.
If you would like a recommendation for your app, tell us what it needs to do and what exists today. We will explain which approach we would choose and why.