
Every mobile kickoff call eventually arrives at the same question: should this be native or cross-platform? Framed that way, it is a religious debate — and religious debates get resolved by whoever argues loudest, not by what the product actually needs. We stopped asking the question that way. Instead we break it into five smaller, answerable questions before a single screen gets designed.
This isn't theoretical for us — we run both stacks in production across a mix of client products, often at the same time, which makes it hard to hide behind a tooling preference. The framework below is the one we actually use on a new mobile engagement, not a retrospective justification for whichever stack the team happened to know best.
Question one: does the product touch the performance ceiling?
React Native and Flutter both render through native widgets or a native-compiled engine, and for the vast majority of business apps — forms, lists, authenticated dashboards, content feeds — the performance gap against native is not something a user will ever notice. The ceiling only matters for a specific, identifiable set of workloads.
- Real-time camera processing or custom ML inference on-device
- Sustained 60–120fps animation driven by physics, not easing curves
- Background audio, Bluetooth peripheral, or sensor handling
- Complex offline-first sync with conflict resolution across large datasets
If none of those apply, cross-platform is not a compromise — it is the correct engineering choice.
Question two: what does the second platform actually cost?
Teams price the first platform and forget the second exists. A native iOS build does not hand you an Android build at a discount — it hands you a second codebase, a second QA matrix, and a second on-call rotation for crashes. Across our own delivery data, a shared React Native or Flutter codebase typically reuses 70–85% of business logic between platforms; the remainder is genuinely platform-specific UI and should be written natively within the cross-platform shell rather than forced into a false abstraction.
Where teams get this wrong
The most expensive mistake is not choosing cross-platform when native was warranted — it's the opposite. A product ships cross-platform at MVP, proves demand, and then a new engineering lead rewrites it natively "for performance" without ever profiling where the frame budget was actually going. Nine times out of ten the real bottleneck was an unoptimized list re-render or an N+1 API call, not the rendering bridge, and the rewrite burns a quarter of runway to fix nothing.
Question three: who maintains this in eighteen months?
A stack decision made for a launch team of six engineers often ages badly once the product moves to a two-person maintenance team. Native means maintaining genuinely separate iOS and Android codebases, including separate dependency upgrades, separate OS-compatibility testing, and separate release cadences — a cost that compounds every year the product stays alive. Cross-platform concentrates that maintenance burden into a single codebase, at the cost of being exposed to the framework's own breaking changes on its own release schedule, which you don't control.
- A small, long-lived internal tool rarely justifies two native codebases' worth of ongoing maintenance.
- A flagship consumer product with dedicated iOS and Android teams can absorb the native maintenance cost and will often be rewarded for it with platform-specific polish.
- If the team hiring natively isn't realistic for the budget, that constraint alone should end the debate — the 'right' answer that can't be staffed isn't actually available.
Our framework, in practice
Define the performance-critical surfaces
List every screen that must hit the ceiling questions above by name. If the list is empty, the decision is already made.
Prototype the hardest interaction first
Before committing to a stack, build the single riskiest screen in both approaches if there's genuine doubt. A two-day spike is cheaper than a six-month bet on the wrong architecture.
Split by surface, not by product
Hybrid is not a dirty word. A cross-platform app shell with one or two native modules for camera or payments is standard practice, not technical debt.
Price the five-year cost, not just the launch cost
Two codebases cost more to staff and upgrade every year the product is alive. Weigh that against the one-time cost of shipping shared logic through a cross-platform bridge.
In closing
Native versus cross-platform is not a values statement about engineering quality. It is five questions with specific, checkable answers, and the teams that answer them honestly ship faster and spend their performance budget on the three screens that actually need it.




