React Native, Flutter, or native: how we actually decide
The "best mobile framework" question has no answer on its own. The team you have and the APIs your app actually needs decide it for you.
Every framework comparison article ends the same way: a table of checkmarks and a shrug. That's because "which is best" isn't a real question — the honest version is "best for this team, this timeline, and this specific list of things the app has to do." We ask three things before we open an editor, and they usually answer it for us.
Start with who's actually shipping it
If the team is mostly web developers who know JavaScript or TypeScript, React Native lets them contribute on day one instead of six months into learning Swift and Kotlin in parallel. If nobody on the team has touched native mobile before, Flutter's single codebase and its own rendering engine mean what you build looks identical on iOS and Android without someone quietly maintaining two slightly different UIs. Neither of those facts is about the framework being "better" — they're about not paying a ramp-up tax you don't have budget for.
Where Flutter tends to win
Flutter draws every pixel itself instead of bridging to native UI widgets, which is exactly why heavily customized, animation-dense interfaces feel more consistent across platforms — there's no native widget quirk to fight. The tradeoff is a smaller plugin ecosystem for the odd native API nobody's wrapped yet, and you'll occasionally write a small native plugin yourself to fill a gap.
Where React Native tends to win
The ecosystem is enormous, Expo strips out most of the native tooling pain for an MVP-stage app, and a team that already ships a web product in React gets real code reuse, not just "the same language." The honest cost: the JavaScript bridge can bite on heavy animation or background work, and the fix is sometimes dropping into a native module anyway — which is fine, as long as you budgeted for the possibility instead of being surprised by it in week ten.
When we skip both and go fully native
Deep OS integration is where cross-platform frameworks strain: background location tracking that has to survive OS battery optimization, Bluetooth peripheral pairing, a camera pipeline doing real-time processing, or a product where raw performance is the product — a game, a camera app, anything where a frame drop is the whole complaint. In those cases we write two native codebases on purpose, because the alternative is fighting the framework for months to get back to where native starts.
The actual decision matrix
- Web team, tight timeline, standard app-shaped app → React Native, usually with Expo.
- No existing mobile or web team, heavy custom UI, need both platforms pixel-identical → Flutter.
- Background processing, hardware peripherals, or performance is the pitch → native, budgeted as two builds from the start.
None of this is permanent — plenty of apps start in React Native or Flutter and drop specific screens into native modules later, once it's clear which 5% of the app actually needs it. Starting there on day one for the whole app is usually solving a problem you don't have yet.