A team we've talked with had shipped a solid React Native app for eighteen months, then needed a feature that streamed processed frames from the camera at low latency for a real-time overlay. The framework could get a camera feed on screen easily enough. Getting it processed frame-by-frame, on the GPU, without dropping to an unusable frame rate, was a different problem — one that needed a native module written against platform APIs that the cross-platform layer was never designed to expose cleanly. That is not a story about React Native being bad. It is the shape of the decision this article is about: a choice that is cheap the day you make it and can become expensive the day your product asks for something the framework didn't anticipate.
Cross-platform or native is not a question with a universally correct answer, and anyone who tells you otherwise is usually selling one side of it. It is a genuine trade-off between delivery speed and platform depth, and the right answer depends on what your app actually needs to do, not on which option sounds more modern.
What native buys you, specifically
"Native is better" is too vague to act on. The concrete cases where Swift/Kotlin earns its higher cost are narrower than the general reputation suggests, but they are real:
- Heavy or sustained graphics work. Custom rendering pipelines, real-time video or image processing, AR overlays, and games with demanding frame budgets benefit from direct access to Metal or Vulkan-adjacent APIs without a bridge layer in the way.
- Background processing with strict OS cooperation. Background audio, continuous location tracking, or long-running background tasks are governed by iOS and Android lifecycle rules that are strict, platform-specific, and change between OS versions. Native code deals with these APIs directly; a cross-platform layer has to keep its abstraction in sync with two moving targets.
- Deep OS integration. Widgets, watch companion apps, CarPlay/Android Auto, custom camera pipelines, or anything that leans on a platform capability the day it ships, before the cross-platform ecosystem has caught up with a mature package for it.
- Extreme, sustained performance sensitivity. Not "the app feels a little less snappy than a native one" — most users never notice that — but workloads where every millisecond of a render loop is the product itself.
Outside of these, the performance gap between a well-built React Native or Flutter app and a native one is smaller than it was five years ago, and for most business applications — forms, lists, dashboards, checkout flows, content — it is not the deciding factor at all. The gap that does still show up reliably is at the tails: cold-start time on older Android devices, memory pressure on long scrolling lists with complex cells, and the first few frames after a screen transition. A careful cross-platform build can get close enough on all three that users don't notice; a rushed one will not, and the difference tends to show up as "the app feels cheap" rather than as any single measurable defect — which makes it easy to under-invest in the areas that need real engineering attention on either stack.
What cross-platform buys you, specifically
The case for a shared codebase isn't "it's cheaper" in the abstract — it's a specific set of operational advantages that compound over the life of a product:
- One feature, one implementation. A pricing change, a new screen, a bug fix — written once instead of twice, tested once instead of twice, and never drifting between platforms because someone forgot to port a fix.
- One team that can hold the whole product in their heads. You are not running two parallel engineering tracks with separate release cadences, separate code review standards, and separate people who each only understand half the app.
- Faster time to a two-platform launch. If your launch date requires iOS and Android on the same day, building twice in parallel with two native teams is a real cost, both in money and in coordination overhead.
- A smaller surface to maintain as the team turns over. Fewer languages, fewer build toolchains, fewer people who are the only one who understands the Android side.
This is the case we make directly on the cross-platform development service page: for a large share of products, a shared codebase is the better economic and delivery choice, and we say so as plainly as we say the opposite when a product needs native depth.
The factor that actually decides most cases: your team
Strip away the framework marketing and the deciding variable in most real engagements is not a technical one — it's what your engineers already know. A team fluent in React and TypeScript will ship a React Native app faster and with fewer defects than the same team learning Swift and Kotlin from scratch, because the framework choice determines how much of their existing judgment transfers. A team that already has strong native iOS and Android engineers, with a UI that needs to feel indistinguishable from a first-party platform app, will do better staying native, because retraining that team into a cross-platform framework throws away exactly the expertise you hired for.
This is why "which is objectively better, React Native or Flutter" is usually the wrong question. React Native tends to suit teams with existing React and web experience and products that share logic with a web front end. Flutter tends to suit teams building highly custom, pixel-consistent UI across platforms who are willing to work in Dart and accept a framework that owns more of the rendering stack. Neither claim is a law; both are defaults worth overriding when your team's actual skills point the other way. Choosing based on a blog post's benchmark rather than on who is going to maintain the app for the next three years is how teams end up capable but slow, writing correct code in a language they're still learning.
Where a shared web-and-mobile codebase changes the calculus
There's a third path worth naming separately: when the mobile app is one surface of a product that also has a substantial web front end, the comparison isn't just React Native versus native — it's whether business logic, API clients, validation, and even some UI components can be shared across web and mobile from the same codebase. This is where the web and app development work and cross-platform mobile intersect directly, because a team already building in React for the web is a short step from React Native for mobile, sharing types, API contracts, and often a meaningful slice of component logic. That shared foundation is a genuine multiplier — one data model, one set of validation rules, one team's mental model of the domain — and it's a strong argument for cross-platform when the product's centre of gravity is really the web app with mobile as an extension of it, rather than mobile being the primary, standalone experience.
When the early cross-platform choice becomes a rewrite
The trade-off that deserves the most honesty is the one that doesn't show up until eighteen months in: a feature the team didn't anticipate needing turns out to require a native capability the cross-platform framework doesn't expose well, and there is no clean shared-code path to it. Sometimes this is solved cleanly — a scoped native module behind a well-defined interface, written once, called from the shared codebase, with the rest of the app untouched. This is the normal, healthy pattern and most production cross-platform apps use it somewhere. But sometimes the feature is central enough — a core interaction the whole product now depends on — that a thin native module isn't enough, and the honest fix is closer to a rewrite of that entire flow in native code, with the shared codebase now carrying a permanent asymmetry between platforms that undoes much of what cross-platform was chosen for in the first place.
The way to avoid discovering this the expensive way is to ask it explicitly during scoping, before any code is written: does this product's roadmap, even the parts eighteen months out, depend on a capability that lives close to the platform? It's worth naming a few concrete warning signs rather than treating this as abstract risk — a roadmap that mentions AR or computer-vision features, wearable or in-car companion apps, sustained background audio or location tracking, or anything described as "as smooth as the native camera app" is a roadmap that should get a native-feasibility check before the framework is chosen, not after a year of building on the assumption it would work itself out. If the honest answer is "we don't know yet," that uncertainty itself is useful information — it argues for shipping the first version cross-platform and validating the product before committing further, rather than guessing wrong in either direction. This is the same discipline we apply to early technical decisions under time pressure generally: some choices are safe to defer or reverse, and some quietly become load-bearing the moment real users and real data depend on them. Framework choice for a mobile app sits closer to the load-bearing end than most teams assume going in, precisely because reversing it later means rewriting UI, navigation, and platform integration simultaneously, not swapping one dependency.
Making the call once, properly
There is no framework that is right by default. Native is worth its cost when the product's value depends on graphics, background processing, or OS integration close to the metal. A shared React Native or Flutter codebase is worth choosing when delivery speed across two or three platforms, one team's shared understanding of the codebase, and a possible shared foundation with a web app matter more than shaving the last few percent off render performance — which, for most products outside of games and heavy media tools, is most of them. The team you actually have, not the team you wish you had, should weigh at least as heavily in that decision as the feature list. And because reversing the choice later is expensive in proportion to how central the affected feature turns out to be, it is worth spending a real conversation on this before the first commit rather than after the first rewrite. If you're weighing this for a specific product, get in touch and we'll work through where your roadmap actually needs platform depth and where it doesn't.