A business does not need to understand programming languages — it needs to describe the product well enough for the choice to be justified: which device features are critical, whether iOS and Android need an identical interface, who will maintain the app in a few years, and whether you already have a team writing React. If the product depends on deep device and platform integration, native development usually wins; if shared code and one design matter more, Flutter or React Native. Uncertain areas are tested with a short prototype before the decision, not after.
Contents
First check whether you need an app-store app at all
The “what to build it in” question only matters if your customers genuinely need an installed app. If the scenario fits in a browser — a catalogue, bookings, an account area with no device features — compare a mobile app with a PWA and a responsive web app first. There is a separate article on that.
The rest of this article assumes an app-store app is needed: for push notifications, offline work, the camera, background location, or presence in the app stores as a sales channel.
The three options in plain terms
Native development
- How it works
- Two separate apps: Kotlin for Android and Swift for iOS
- Business strength
- Full and early access to platform capabilities, behaviour that feels like the system
- The cost of the choice
- Two codebases, two skill sets, every feature built twice
Flutter
- How it works
- One codebase in Dart; Flutter's own engine draws the interface instead of system controls
- Business strength
- One design across platforms and OS versions, one UI codebase
- The cost of the choice
- Requires Dart specialists; system controls are reproduced rather than used directly
React Native
- How it works
- One codebase in TypeScript using the React model; real native components on screen
- Business strength
- Lets you reuse a React web team's experience and share code with a web product
- The cost of the choice
- Depends on the library ecosystem; some features still need native code
All three options are mature. Since version 0.76, React Native enables the New Architecture by default: the asynchronous “bridge” between JavaScript and native code is replaced by the JSI interface. Flutter's documentation says it implements every UI control itself instead of relying on system widget libraries — which is why an app looks the same across OS versions.
There is also a middle path — Kotlin Multiplatform: shared business logic is written once, while the interface can stay native on each platform or be shared too via Compose Multiplatform. It suits a team that is already strong in Kotlin and wants to keep a native UI.
Six product questions that decide the choice
Which device features are critical
Camera, Bluetooth devices, NFC, background location, widgets, watches, in-app payments. Cross-platform frameworks reach these through native code — platform channels in Flutter, native modules in React Native. The more such places there are, the more native code a “cross-platform” project will contain and the smaller the benefit of shared code.
What the interface should be like
If a recognisable brand design that looks identical on every phone matters, that argues for Flutter. If users expect their platform's familiar behaviour, native and React Native with system components are stronger.
Who will maintain the app
An app lives for years, and the people who evolve it are not necessarily those who wrote version one. Check for yourself which specialists are easier to find in your city and working model: look at job postings and CVs, not popularity rankings. If you already have a React and TypeScript web team, React Native lets you build on their experience.
How often you need to ship updates
With React Native and Expo, some changes (JavaScript, styles, images) can be delivered over the air via EAS Update. Changes to native code, permissions or the SDK version still require a new build, and updates must follow app store rules.
Whether you are ready for mandatory platform updates
The stores raise their requirements regularly. For example, from 31 August 2026 new apps and app updates on Google Play must target Android 16 (API level 36) or higher. So a maintenance budget is needed with any stack — “build it and forget it” is not an option.
What data the app stores
If the app handles payments, medical or personal data, define requirements for on-device storage, network communication and authentication up front. OWASP MASVS, the security requirements standard for mobile apps with groups such as STORAGE, NETWORK, AUTH and PRIVACY, is a useful reference.
Trade-offs that rarely come up in a sales pitch
How it sounds in a proposal
- “One codebase, so half the cost”
- “Native is always faster and better”
- “The framework can do anything”
- “Updates without the store”
What to check in practice
- Testing, publishing and review still happen on two platforms, and platform specifics still need separate attention
- Native gives full platform access but needs two codebases and two skill sets; for typical screens users may notice no difference
- Third-party plugins for rare features may be immature — check your specific features
- Over-the-air updates change only part of the app, and store rules still apply
There is also a long-term trade-off: a cross-platform framework is one more layer between your product and the platform. Keeping it up to date is regular work to plan for, just like iOS and Android updates themselves. A native app avoids that layer, but every new feature costs twice.
The right choice is not the trendiest one, but the one you can still maintain after the first team has left.
A decision procedure
Feature list
List the app's features and mark each one “critical for launch” or “nice to have later”. Highlight the features that depend on the device.
Risk map
For the critical features, find out whether each option supports them maturely. Features with no ready solution are the main candidates for native code.
Prototype the uncertain part
If doubts remain, build a short technical prototype of the riskiest feature on the chosen stack. That is cheaper than discovering a limitation halfway through the project.
A written decision
Record the choice, the reasons, the rejected options and the condition under which the decision should be revisited — for example, a new feature the stack cannot support.
Acceptance criteria
Make testing on real devices for both platforms and publishing to both stores part of acceptance, not “later”.
Scope depends on the variables collected in these steps: the number of screens and scenarios, how many features need native code, integrations with your systems, whether a backend and API already exist, the number of platforms at launch and the support plan. The cost is determined after a brief and an agreed scope — no stack makes a project cheap or expensive by itself.
Questions for the contractor and next step
- Why does this stack suit our product specifically — which of our features drove the choice?
- Which features will need native code, and who on the team will write it?
- What happens when a new iOS or Android version ships, and is that covered by support?
- Which changes can ship without the store, and which need a new build and review?
- Whose names will the developer accounts and app signing keys be registered under?
- How will testing on real devices for both platforms be done?
- How is the code handed over, and what does another team need to continue the app?
Limitations: this article covers the product-level choice and does not replace checking specific libraries against your features. Store requirements and framework versions change — verify them against official documentation on the date you decide.


