Mobile apps

Native app, web app or PWA: an architectural choice, not a fashion one

Native, cross-platform, web app or PWA: the real limits of PWAs on iOS, hardware access, distribution, maintenance costs and the technical criteria for deciding.

Fabio Folgori5 min read

Collection of old mobile phones from different eras
Photo by Tasha Kostyuk on Unsplash

The question "do we need an app?" almost always comes with an answer already in mind: the icon in the store. But choosing between native, cross-platform, web app and PWA is not about the icon. It is about hardware access, distribution, maintenance costs over time and how many codebases have to be kept alive. It is an architectural choice, and it is worth making on technical grounds.

The four options, briefly

  • Native app: Swift for iOS, Kotlin for Android. Two codebases, full access to system APIs, maximum performance.
  • Cross-platform: React Native or Flutter. A single codebase producing native interfaces on both systems, with native modules where needed.
  • Web app: an application in the browser, one codebase for every device and instant updates.
  • PWA: a web app with a manifest and service worker, installable on the Home Screen, with offline support and notifications.

Halfway sits Capacitor: a web app wrapped in a native shell, publishable in the stores and with access to device plugins.

The real limits of PWAs

PWAs were long promoted as the universal answer. Today they are much more mature, but on iOS there are differences to know:

  • push notifications work from iOS 16.4 only for PWAs added to the Home Screen, and the user has to do that step manually;
  • background sync and some APIs (Bluetooth, NFC, extended file system access) are unavailable or only partly available;
  • storage can be cleared by the system if the app is not used for a while;
  • there is no store presence, which for some projects is an acquisition channel and for others irrelevant.

On Android and desktop the limits are much smaller. If the audience is mostly internal (staff, members, existing customers) on mixed devices, a PWA often covers 100% of the needs.

When native is really needed

Native or cross-platform become necessary when:

  • the app uses hardware heavily: Bluetooth Low Energy, sensors, camera with real-time processing, background location;
  • high graphics performance or complex 60 fps animations are needed on low-end devices;
  • the store is the channel through which people find the service;
  • the app must work offline for long periods with reliable sync.

Between pure native and cross-platform, for most projects I see cross-platform is the best compromise: one codebase, two stores, native modules only where needed.

The cost you do not see in the quote

A store app is not delivered once. Every year Apple and Google release new OS versions, change publishing requirements, deprecate APIs and raise minimum SDK levels. The project's native libraries have to be updated accordingly. With two native apps, the work doubles.

A web app or PWA updates with a deploy, without store review and without users stuck on old versions. That difference in operating cost weighs more than the upfront cost.

The backend is what lasts

Whatever the client, the part that lasts longest is the backend: APIs, authentication, data, integrations. Designing it well, with documented APIs independent of the client, lets you start with a web app and add a native client later without rebuilding anything. The most expensive mistake I see is an app built with its logic inside the client, which becomes impossible to bring to another platform.

How I decide

The questions I ask at the start:

  1. Who uses the app, and do they find it in a store or receive it from the service provider?
  2. Which device features are really needed, not "might be needed"?
  3. How much must it work offline, and with what kind of sync?
  4. Who will maintain it in three years, and with what yearly budget?
  5. Is there already a web app or management system to start from?

If the answers do not point to specific hardware or the store as a channel, I suggest starting from the web.

Offline and sync, the most underrated part

"It works offline too" is a phrase that hides a lot of work. In a PWA the service worker decides what to serve from cache and what to fetch from the network: static assets from the cache, data from the network with a cache fallback, pages refreshed in the background. Data the user creates without a connection must be stored locally, in IndexedDB, and sent to the server when the network returns.

The real problem is conflict: two devices edit the same record offline, or the record changed on the server in the meantime. You need an explicit rule, agreed with whoever knows the process: last write wins, the server wins, or the user is asked. Without that rule, sync loses data silently.

On iOS, background sync for PWAs is limited, so sending happens when the app is reopened. For many use cases (checklists, notes, forms filled in the field) that is fine; for an app that must sync continuously even when closed, it is an argument for native or cross-platform.

My take

My preference is clear: web app or PWA as the first choice, native when the requirements demand it. Not out of laziness, but because a single codebase, updated with a deploy, lowers the cost of the whole lifecycle. The Altura Vela management app and the Fix and Sail platform are Nuxt web applications used daily on phones, and neither needed a store to work.

When something closer to the device is needed, it is done carefully: with VeWorld, for example, I worked on the React front end of a Chrome extension, where the execution context imposed precise constraints. The choice of tool always comes after the requirements, never before.

Why work with me

I have been programming since 1999, delivered more than 300 projects and work as an external developer with about 30 agencies, from Rome and remotely. I build web apps, PWAs and cross-platform apps, and design the backend so the client can change without rebuilding everything.

If you are considering an app, get in touch: in a call of about 20 minutes we work out which architecture your case really needs. The service is in Mobile apps.

Frequently asked questions

Yes, since iOS 16.4, but only if the user has added it to the Home Screen. Limits remain on background sync and some hardware APIs, which must be checked for the specific case.

React Native and Flutter produce native interfaces from a single codebase and suit highly interactive apps. Capacitor wraps an existing web app in a native shell: it pays off when the web app already exists and you need store presence and a few device features.

Yes, and it is often the best route: the APIs and backend stay, and a native client is added when usage data shows it is needed.

Besides developer account fees, there is the work of adapting to every new iOS and Android version, store requirements and native libraries. It is a recurring cost to budget for from the start.

  • #mobile app
  • #native app
  • #pwa
  • #web app
  • #cross-platform app

More articles

// Contact

A project, a problem or just a question?

Agency, business or professional: choose how you'd rather talk to me. I reply within one working day, no strings attached.