Home/ Blog/ Article

Native, cross-platform or PWA: choosing a mobile app architecture

ยท

Most conversations about mobile apps start in the wrong place. A founder or product lead asks “should we use Flutter or React Native”, when the question that actually determines cost, timeline and long-term maintenance is one step earlier: does this app need native, cross-platform, or a progressive web app (PWA) at all. Get that fork wrong and the framework choice underneath it stops mattering.

The honest answer is that none of the three options is universally better. Each trades distribution, device access and maintenance overhead differently, and the right one depends on what the app has to do, not on which approach is currently fashionable.

What a PWA actually buys you

A PWA is a website that behaves like an app: it can be added to a home screen, cache assets for offline use through a service worker, and send push notifications (including on iOS, since Apple added web push for home-screen PWAs). There is no app store review, no separate iOS and Android codebase, and updates ship the moment you deploy, without waiting on a review queue.

The trade-off is device access. A PWA can use the camera, geolocation and basic notifications through browser APIs, but it has no reliable route to Bluetooth Low Energy scanning in the background, no NFC on iOS, and no dependable background execution once the browser tab is closed. If the product’s value depends on any of that, a PWA is not a compromise, it is a different product.

Where a PWA is the right call: internal tools, dashboards, booking or ordering flows, anything where reach and instant updates matter more than deep hardware integration, and where App Store presence is not itself part of the distribution strategy.

What cross-platform buys you, and where it stops

Flutter and React Native let a team write one codebase and ship to both iOS and Android, compiling down to something close to native rather than running inside a browser wrapper. For the bulk of a typical business app – forms, lists, authentication, API calls, standard navigation – the performance difference against fully native is not something most users will notice.

The catch is what happens at the edges. The moment an app needs something the framework’s plugin ecosystem does not cover well – custom Bluetooth mesh protocols, low-latency camera pipelines, background telemetry that has to survive OS process killing – the team ends up writing native modules on both platforms anyway. At that point the “one codebase” saving shrinks, because you are maintaining native Swift and Kotlin code plus the cross-platform layer that calls into it.

We see this pattern directly in our own products. Mesh Messenger, our offline peer-to-peer messenger, depends on Bluetooth and WiFi Direct behaving predictably in the background across manufacturers, which is squarely native-module territory regardless of the framework wrapped around it. Our IoT platform work involves BLE device pairing and telemetry that has the same requirement. A cross-platform shell works well for the screens around that core, but the core itself is native either way.

When native is still the right default

Fully native makes sense when the app’s core value is exactly the kind of edge case above: sustained background hardware access, camera or video processing where every millisecond of latency is visible to the user, or deep integration with platform frameworks that cross-platform bridges support inconsistently or late. Our webcam and video monitoring platform is a good example – low-latency video handling and platform-specific camera APIs are worth the cost of two native codebases when the product’s whole premise is real-time video quality.

Native also tends to win when the two platforms genuinely need different user experiences rather than a shared one, or when the team already has separate iOS and Android engineers and a cross-platform migration would cost more in retraining than it saves in shared code.

The real cost is maintenance, not the first build

Whichever option looks cheapest to build is not necessarily the cheapest to run. Two native codebases mean two release cadences, two sets of OS version quirks, and two app store review cycles every time you ship a fix. Cross-platform reduces that to one release process most of the time, but you still carry both platforms’ store review and both platforms’ OS updates breaking things on their own schedule. A PWA removes store review entirely, but you inherit browser fragmentation and the risk that a platform (historically iOS) changes what PWAs are allowed to do with little warning.

None of this shows up in a first-quarter budget. It shows up eighteen months in, when the app needs a new OS-level permission, a background execution change, or a store policy update, and the cost of that change depends entirely on which architecture you picked at the start.

Questions worth answering before the framework conversation

  • Does the app need background hardware access (Bluetooth, NFC, sustained camera or sensor use)? If yes, budget for native modules regardless of the wrapper you choose.
  • Is app store presence part of the distribution strategy, or is a link and an install prompt enough? If discovery genuinely depends on store search and rankings, a PWA is the wrong starting point.
  • What does the team already know? A strong web team building a Flutter or React Native app for the first time will be slower than the same team shipping a well-built PWA, at least for the first release.
  • How different do iOS and Android need to look and behave? Products with heavily platform-specific interaction patterns get less benefit from a shared codebase than products where the UI is largely the same on both.
  • Who owns this app in two years? If long-term maintenance falls to a small internal team, minimising the number of codebases and release pipelines usually matters more than shaving weeks off the first build.

There is no version of this decision that is purely technical. It is a trade between what the app must physically do, who maintains it once it ships, and how much distribution depends on being inside an app store rather than a browser. Answer those three questions first, and the framework choice tends to answer itself.

Filed under: