TL;DR: For most startup apps, the choice between React Native, Flutter and fully native is less about benchmarks and more about three questions: who will maintain this in two years, how much of the app has to touch the operating system, and whether you already have a web product. If you have a React or Next.js web app and a JavaScript team, React Native usually wins because the people, the types and often the API layer are shared. If you are mobile-only and want pixel-identical UI on both platforms with one strong team, Flutter is a very good choice. Go fully native when the hard part of the product lives inside the OS: background services, VPN tunnels, deep hardware access, or platform features that ship before any framework supports them. And if the core of the product is 3D, AR or real-time interaction, the honest answer may be none of the three: it may be Unity. I have shipped React Native apps as CTO at RAQTS, built a React Native VPN on top of native tunnels at Geonode, written Swift and Kotlin where frameworks ran out, and worked in Flutter and Dart, so this is the decision process I actually use with founders.
Founders usually arrive at this question from a blog post or a developer's preference. One article says Flutter is faster. A friend says React Native is what Meta uses. A senior iOS engineer says cross-platform always ends in tears. All of those can be true for somebody. None of them answers the question for your product.
Start with the team, not the framework
The framework you pick is mostly a hiring and maintenance decision wearing a technical costume. The app will outlive the first version by years, and the people who keep it alive matter more than whatever the framework scores on a scrolling benchmark.
Ask who is going to own the codebase after launch:
- A JavaScript or TypeScript team, or a web product already in React. React Native lets the same engineers move between web and mobile, and lets you share types, validation logic and API clients. At RAQTS, the product lived across React Native mobile apps, a Next.js web portal and a Unity interactive layer called Lumo. Having two of those three in the same language family was a real advantage, because a change to how leaderboard data was shaped could be reasoned about once rather than translated between languages. I wrote about holding that product together in stepping in as CTO at RAQTS.
- A small, dedicated mobile team with no web product. Flutter is a strong fit. Dart is easy to pick up, the tooling is coherent, and one team can own both platforms comfortably.
- Separate iOS and Android specialists already on staff. Native is reasonable, and arguably the default, if you can afford two codebases and the people to keep them in step.
If you are a non-technical founder hiring a contractor, add one more question: can you hire a replacement for this person in this stack? That is not a judgement on any framework. It is about not being stuck. The same logic is behind my advice in how to hire a Unity developer: own the repository, the store accounts and the signing keys, and pick a stack you can staff.
Then ask how much of the app touches the operating system
This is the question that most often decides it, and it is the one that comparison articles skip.
Every app has two parts. There is the part that is screens, forms, lists and API calls. And there is the part that talks to the operating system: background execution, push behaviour, Bluetooth, the camera pipeline, networking at the system level, widgets, payments, health data, and anything the OS treats as privileged.
Cross-platform frameworks are excellent at the first part. For the second part, every one of them falls back to native code eventually. The question is how much of your product lives there.
When the OS layer is small
A booking app, a marketplace, a social feed, a dashboard, a companion app for a web service. The OS work is push notifications, a camera picker, maybe deep links. All three options handle this fine, and cross-platform saves you a second codebase. Pick on team fit and move on.
When the OS layer is the product
At Geonode I built a React Native VPN, and the lesson was blunt: the VPN itself cannot be written in React Native. On Android the tunnel is a VpnService. On iOS it is a Network Extension running as a separate process with its own memory limits. React Native was the remote control, the screens where users connect, see status and change settings. The engine was native on both sides. I went through that boundary in detail in building a React Native VPN app.
That project was still a good use of React Native, because the UI was genuinely shared and the native parts were well contained. But a founder who had been told "we will write it once" would have been badly surprised. Before choosing, list every feature that needs OS privileges and ask, for each one, "who writes the native part, and in which language?" If the answer is "most of the product, in Swift and Kotlin", go native from the start.
The same was true of the Repocket SDK I built at Geonode: the networking logic had to behave correctly across Windows, Android and iOS, and the shared core only worked because the platform-specific parts were kept on their own side of a clear line. I wrote that up in one C# SDK across three platforms. Whatever framework you pick, that line is where the real engineering happens.
React Native: when I reach for it
React Native is my default for startups that already have, or will soon have, a React web product.
Where it is strong:
- Shared language, tooling and often types with a React or Next.js web app.
- A huge hiring pool, since most web engineers can become productive in it.
- Over-the-air updates for JavaScript changes, within the store rules, which can shorten the gap between finding a bug and fixing it.
- A mature ecosystem for the common things: navigation, auth, payments, analytics, push.
Where it costs you:
- Native modules. Anything outside the ecosystem means writing or maintaining Swift and Kotlin bridges, and upgrades can break them.
- Upgrades in general. Moving React Native versions on a live app takes planning, much like upgrading Unity on a live project, because third-party native dependencies move at different speeds.
- Very animation-heavy or custom-rendered UI takes more care to keep smooth on mid-range Android phones.
Flutter: when it is the better call
Flutter draws its own UI rather than wrapping native components, and that design choice explains most of its trade-offs.
Where it is strong:
- UI that looks and behaves identically on iOS and Android, which designers love and QA appreciates.
- Smooth custom animation and highly branded interfaces, because the framework owns every pixel.
- A coherent, opinionated toolchain that one team can learn end to end.
Where it costs you:
- Dart is a separate language from your web stack, so less sharing with a React web product.
- Platform-native look and feel takes deliberate work, since you are not getting native components by default.
- The same native-code reality as React Native for OS-level features. Platform channels are clean, but someone still writes the Swift and Kotlin.
If a founder tells me "mobile is the whole business, we have no web app, and the brand lives in the interface", Flutter is often the answer I give.
Fully native: when the cost is worth it
Two codebases is a real, ongoing cost. Every feature is built twice, tested twice and released twice. You go native when that cost buys something you cannot get otherwise:
- The core of the product depends on OS capabilities that frameworks wrap late or poorly.
- You need the newest platform features on launch day, not when a plugin catches up.
- Performance or battery life is a competitive feature, not just a nice-to-have.
- You already have strong iOS and Android engineers.
Native also tends to be the easiest stack to hand to the next team, because the documentation is the platform's own. That matters more than people think when someone eventually has to inherit the codebase.
The option nobody mentions: Unity
If the heart of your app is a 3D scene, an AR experience, a game-like interaction or a real-time visual, the comparison above is the wrong one. Unity is a serious cross-platform option for non-game products, and I spent years using it that way: AR tools and the ERIS XR platform at ARCortex, clinical eye-tracking diagnostics on the Vive Focus 3 at Nystag, and the Lumo interactive platform at RAQTS. I wrote about when Unity fits a non-game app. The usual pattern is Unity for the immersive part, and a conventional app or web portal for accounts, settings and data, talking to the same backend.
Decisions that matter more than the framework
Whichever stack you pick, a few choices in version one decide how painful the next two years are:
- Keep business logic on the server. The less the client decides, the less it matters which framework the client is written in.
- Design for old app versions. Store review and slow updaters mean you will always have several versions in the wild. Ship a minimum-version gate and remote flags in version one. I covered that in designing a backend for old mobile app versions.
- Get builds off laptops early. Signing keys and release builds belong in CI, not on one engineer's machine. The Unity CI/CD notes I wrote apply almost unchanged to React Native and Flutter.
- Write down the native boundary. A one-page list of what is native, in which language, and who owns it saves weeks later.
My short version
- You have a React web app or a JavaScript team: React Native.
- Mobile-only, brand-heavy UI, one dedicated team: Flutter.
- The product lives inside the OS, or you already employ native engineers: native.
- The product is a 3D, AR or real-time experience: Unity, alongside a conventional app for the rest.
Then spend your energy on the backend, the release pipeline and the native boundary, because that is where mobile products actually succeed or fail. The framework is the decision people argue about. It is rarely the one that sinks the project.
I build mobile, web, XR and AI products for founders, and take on fractional CTO roles for teams that need technical direction. If you are choosing a stack for a new app, or living with one that is not working, more about my background here, or book a call and we can work out which fits your product.