Before you weigh anything we say about this, you should know our bias. Every phone app we have shipped is React Native, and so is every one we have in progress: six codebases, including Pakka's customer and driver apps on Google Play and LeafRanger's 93-screen plant app, which is still launching. We take Flutter work, and we will tell you when Flutter is the better call. But we have not shipped a Flutter app of our own, and pretending to be a neutral referee would be the first dishonest thing in this post.
With that on the table, our answer for a new product is short. If the people who will maintain the app write JavaScript or TypeScript, build it in React Native. If they write Dart, or you already have a Flutter app that works, stay with Flutter. Almost everything else people argue about matters less than that one question.
The table we actually use
When a founder asks us to choose, we don't start with benchmarks. We go down this list, and the rows near the top outweigh the rows near the bottom.
| Question | Points to React Native | Points to Flutter | How much it should weigh |
|---|---|---|---|
| Who maintains the app in two years? | A team that writes JavaScript or TypeScript | A team that writes Dart | Most of the decision |
| Is there working code already? | A React Native app, or a React web app to share code with | A Flutter app that works | Nearly as much. Rewriting a healthy app buys you very little |
| Does one team need to cover app, web console and backend? | Yes: one language across all three | Less important if the web side is someone else's job | A lot, for small teams |
| How should the interface feel? | Like a normal Android or iPhone app, with the system's own controls | A custom, heavily branded design that must look identical everywhere | Moderate |
| Desktop or kiosk from the same code? | Possible, less common | Mature enough for internal tools | Only if you need it |
| Which native SDKs do you need? | Check each one has a maintained package | Check each one has a maintained package | A tie. Check package by package |
| Speed for a typical business app | Fast enough | Fast enough | Close to zero |
| Store review | Same rules | Same rules | Zero |
If the top three rows agree, stop reading comparison articles and go build. If they split, the first row wins.
Why the people row outweighs everything
An app is built once and maintained for years. The build is the short part.
On Pakka, a delivery platform with a customer app, a driver app, a business portal and an operations console, the same TypeScript runs through the phone apps, the web consoles and the backend. Validation rules and types are shared between app and server, so a bug that starts in the app and ends in a server rule can be chased by one person, in one language, without a handoff. That is the real argument for React Native in a small team, and it has nothing to do with frame rates.
The mirror image is just as true. If you already have two Dart developers, choosing React Native throws away the thing you paid most for. Our Flutter app development page exists because that situation is common: a team that chose Flutter for good reasons and needs more hands, a backend or a release process.
What drawing the interface changes
The one technical difference worth understanding is who draws the screen. Flutter ships its own rendering engine and paints every pixel itself. A button on Android and a button on iPhone are the same drawing, so a custom design matches everywhere and animates identically. React Native asks each platform to draw its own native controls, so a text field on an iPhone really is Apple's text field. The app feels at home on each phone, and the two versions differ in small ways because the platforms do.
Neither is better in general. If your brand lives in a custom animated interface, Flutter's approach is a real advantage. If your app should behave like every other app on the phone, React Native gets that for free. Most business apps (bookings, deliveries, coaching, marketplaces) work well either way. The React Native glossary entry has the plain-language version, and our comparison with fully native apps covers the question of skipping cross-platform altogether.
The bugs that ignore your framework
Here is the part of the debate that wastes the most time. The problems that actually held up our releases would have happened in Flutter too.
Google Play rejected Pakka's driver app on 23 October 2026 because our own one-time-password limit locked the reviewer out. On Android 15 and later, the keyboard covered the delivery-code boxes, so driver app 1.0.19 keeps them above it. iPhones pause apps in the background, and a server rule that marked drivers offline after five minutes of silence had to become 30 minutes for iPhone drivers. A scheduled-time wheel went unreadable in dark mode on iPhone.
Not one of those was a React Native problem. They were platform behaviour, store policy and our own server logic. A framework does not protect you from any of it. Real phones and a release checklist do, which is why our Google Play launch checklist never mentions a framework.
Where native code turns up
Both frameworks reach the camera, location, maps, push and payments through packages, and both let you drop into Kotlin or Swift when a package isn't enough. In practice, that drop is rarer than people fear.
Across our six React Native codebases, the only substantial native module is LeafRanger's subscription billing. It started on a third-party cross-store layer. Because LeafRanger launches on Android first, on 10 September 2026 we replaced it with our own module over Google's billing library, behind the same purchases wrapper, so no screen file changed. The server verifies each purchase with Google before granting the plan. Store billing for in-app purchases is the most likely place you will meet native code in either framework, and the LeafRanger case study has the longer account.
So the useful question is not "does this framework support payments?" It is "is there a maintained package for each SDK on my list, in this framework, today?" We check that one SDK at a time before recommending either.
Cost and speed: closer than you'd think
For the same scope, the framework barely moves the price. The bill is set by how many apps, how many user roles, whether you need your own backend and admin console, payments and payouts, live tracking. The flows, the API, the database, the store release are the same work in either. Our React Native cost page breaks down what moves the number, and a Flutter app of the same scope lands in the same place.
Speed is similar. Pakka's whole platform was in production in under 15 weeks, and the time went into dispatch, payments, invoicing and consoles. The app framework was never the bottleneck. A team fluent in one framework will be faster in it for the first few weeks, which is one more vote for the people row.
If you already have an app
Then the question changes from "which framework?" to "what state is it in?". Before anyone quotes new features on an inherited app, we build it from a clean checkout on current tools, check how far behind it is on framework version and store targets, list abandoned packages, and find out who holds the signing keys. That read is the same for both, and our code audit covers JavaScript, TypeScript and Flutter apps at a fixed price. Our app takeover page describes the longer version.
In most cases, fixing or finishing the existing app costs less than rewriting it in the other framework. A rewrite keeps the backend, designs and data, and throws away the screens, navigation and app logic. Switch only when the people you can hire know the other framework, or the app needs something its framework does badly.
Our verdict, with the bias still showing
For a new product with no reason to prefer Flutter, we recommend React Native, and that is what our mobile app development and React Native app development pages describe. If our track record matters more to you than the framework, that is an honest reason to pick it too.
For a team that writes Dart, or a Flutter app that works, stay with Flutter and don't let anyone, us included, talk you into a rewrite. When it's genuinely close, we write the choice down during a Discovery Sprint, with the reasons and the package list, so the decision survives the next change of team.