This question comes up on nearly every mobile project kickoff. There’s no universal answer, but there is a useful way to think about it.

Choose native when performance or platform depth matters most. Heavy animation, camera/AR work, or apps that need to feel indistinguishable from platform-first apps usually justify native Kotlin and Swift, even with two codebases to maintain.

Choose Flutter for a consistent look across platforms, fast. Flutter’s single codebase and consistent rendering engine make it a strong pick when brand consistency across iOS and Android matters more than deep platform-specific behavior.

Choose React Native when the team is already a React shop. Sharing knowledge and sometimes code with an existing web team can outweigh the technical tradeoffs, especially for a lean startup team.

Budget and timeline are real inputs, not excuses. A cross-platform framework that ships an MVP in half the time is often the right business decision, even if it’s not the “purest” technical choice.

I’ve shipped successful apps in all three. The framework rarely determines success, the fit between the tool and the actual constraints does.

Questions I ask before recommending a framework

How much of the UI needs to feel platform-native? Flutter renders its own widgets rather than using each platform’s native components, which gives pixel-perfect consistency but can feel very slightly “off” on iOS specifically, where users are used to native motion and text rendering. Google’s own Flutter architectural overview is worth reading to understand exactly what that tradeoff involves technically.

What’s the team’s realistic ramp-up time? A React web team can usually be productive in React Native within a couple of weeks. The same team learning Flutter’s Dart language and widget model from scratch takes meaningfully longer, which matters if the timeline is tight.

How deep does the third-party integration need to go? Native platform SDKs, especially newer or more obscure hardware integrations, often land on native Kotlin and Swift first and reach cross-platform frameworks later, if at all. A niche hardware integration can quietly force the native decision regardless of every other factor.

What does long-term maintenance actually look like? Cross-platform frameworks add a dependency on the framework’s own release cadence and breaking changes, on top of the usual OS updates. That’s a real, ongoing cost that’s easy to underweight during an initial kickoff focused on getting to launch.

There’s rarely a wrong answer here, only a wrong fit for the specific constraints. Once the framework is chosen, the bigger cost driver is usually scope discipline, which I cover in Common Mistakes First-Time App Founders Make.

Two projects, two very different right answers

A restaurant chain wanted a single ordering app that felt identical across iOS and Android storefronts in every city, with a modest engineering budget and a tight six-week timeline. Flutter was the clear right call: one codebase, consistent branding down to the pixel, and a small team able to maintain both platforms without doubling headcount. A separate client building an AR furniture-placement app needed deep native camera and ARKit and ARCore integration that neither cross-platform framework could reliably deliver at the fidelity required. That one was native from day one, with no real alternative on the table.

Neither decision was close to controversial once the actual requirements were listed out. The framework debate only gets contentious when it’s argued in the abstract, “which is better”, rather than against a specific product’s specific constraints, team size, timeline, platform depth needed, and long-term maintenance appetite.

I’ve stopped having the “which framework is best” conversation in the abstract entirely. The only useful version of that conversation starts with a requirements list, and the framework choice falls out of it almost on its own.

A decision framework you can actually reuse

Rather than re-litigating this question from scratch on every project, I now score each option against five factors for a specific product: platform depth needed, team’s existing skillset, timeline pressure, budget for two codebases if native, and how much a slightly-off native feel would actually matter to the target users. Scoring each framework one to five against those factors, honestly and specifically for the product at hand rather than in the abstract, turns a debate that can otherwise drag on for weeks into a decision that usually becomes obvious within a single working session.

The factor most teams weight incorrectly is the last one, how much a slightly-off native feel matters to real users. For an internal business tool used by employees who have no choice but to use it regardless of polish, this factor barely matters. For a consumer app competing against native-first incumbents in a crowded category, it can be the deciding factor all on its own, because users comparing your app directly against a platform-native competitor will notice subtle rendering and motion differences even if they cannot articulate exactly what feels off.

Being explicit about which factors matter most for a specific product removes most of the emotion from what is otherwise often treated as a matter of personal preference between developers who each have a favorite tool.

Whichever framework you land on, the decision is rarely permanent or fatal if it turns out imperfect. Teams have successfully migrated between all three when a product’s needs changed enough to justify it, so the bar for the initial decision should be good enough to start, not perfect enough to never revisit.

The right framework is simply the one that lets a specific team ship a specific product well, nothing more mysterious than that.

The framework decision gets easier every year as all three ecosystems mature and the gaps between them narrow. What used to be a decision with serious long-term consequences is increasingly a decision about near-term team fit, which is a much lower-stakes question to get right.

A lower-stakes decision is a much easier one to make with confidence.

Whichever framework gets chosen, the team that ships something real and learns from actual users will always beat the team still debating the theoretically perfect technical choice from the sidelines.

Ship, learn, adjust, repeat, that loop matters more than which framework happened to be chosen at the very start of it.