What is a PWA? Definition, architecture & decision framework
Contents
A product team ships a responsive web app, watches bounce rates on slow mobile connections, and assumes the answer is a native app rewrite, six months and $200K later. In most cases, a progressive web app would have solved the same problem in eight weeks.
What a PWA is, the 30-second answer
A PWA is a web app that installs on any device and works offline, built on three browser primitives: a service worker, a web app manifest, and an HTTPS origin requirement. Strip any one of those three and the browser won't trigger the add-to-home-screen prompt; the experience degrades silently to a plain website. Understanding exactly what that contract requires, and where it still falls short, is what separates a grounded build decision from a marketing talking point.
Our engineering team has audited and rebuilt more than 30 web products as PWAs for fintech, retail, and SaaS clients; the recurring gap we find is a missing fetch-event handler that silently blocks installability, often on codebases that already have the manifest and HTTPS in place. Fix that single handler and most blocked installs resolve immediately. The definition is simple; the implementation detail that matters most is the service worker's fetch event.
The three-part contract: Service worker, manifest, HTTPS
A PWA earns its installability through three interdependent browser primitives: a service worker, a web app manifest, and an HTTPS origin. Remove any one and the browser refuses to trigger the add-to-home-screen prompt, the app silently reverts to a standard browsing session.
Service worker, the programmable network proxy registered in a separate thread from the main JavaScript execution context. Its lifecycle runs through two critical moments: the install event, where the worker pre-caches the app shell into Cache Storage, and the fetch event, where it intercepts every outgoing request and decides whether to serve from cache, hit the network, or blend both. The strategy you choose here, cache-first, network-first, or stale-while-revalidate, determines your offline behavior and your perceived load time. The MDN Cache API reference defines the exact storage interface; cache entries are string-keyed Request/Response pairs, not a generic key-value store.
Web app manifest: a JSON file, linked from your HTML `<head>`, that tells the browser how to present the installed app: name, icon set, display mode (standalone removes browser chrome), start_url, and theme_color. The W3C Web App Manifest specification sets the minimum viable fields for installability; Chrome additionally requires a 192×192 and a 512×512 PNG icon and a start_url reachable within the HTTPS origin.
HTTPS origin requirement, service workers can only register on secure origins. This is not a Chrome policy quirk; it is a WHATWG Fetch specification constraint tied to the integrity of the fetch event interception model. A service worker on an HTTP origin could silently rewrite responses, a man-in-the-middle by design. localhost is the one carved-out exception for local development.
These three form a contract: the manifest declares intent, the service worker fulfills the offline promise, and HTTPS guarantees the interception cannot be tampered with in transit.
How service workers intercept requests
Service workers intercept every network request the PWA makes, acting as a programmable proxy that sits between the application and the network, making fetch-event handling the core of any offline-capable design.
Three caching patterns cover the majority of real-world PWA architectures:
Cache-first serves the cached response immediately and never hits the network unless the cache is cold. Use this for static assets that rarely change: fonts, icons, and the app shell architecture skeleton. A SaaS dashboard benefits here because the chrome of the UI loads in under 100ms regardless of connection quality, and the Cache API stores versioned asset bundles written at build time (Catchpoint 2025 SaaS Website Performance Benchmark Report).
Network-first tries the network and falls back to the cache only on failure. The right choice for authenticated API calls where stale data causes real harm, a fintech balance widget, for instance, must not display a cached figure as current. The tradeoff is that every request takes a round-trip on a good connection, so this pattern carries a latency cost.
Stale-while-revalidate returns the cached version immediately, then fires a background fetch to refresh the cache for the next request. This is the sweet spot for content that updates frequently but where a one-request lag is acceptable, a product catalog or a CMS-driven editorial feed. An ecommerce client we worked with in 2024 shifted their category listing to stale-while-revalidate and cut perceived load time by roughly 60% on repeat visits without ever serving content more than a single cache cycle out of date.
The Background Sync API extends this model to writes: form submissions and cart mutations queued while offline replay automatically when connectivity returns, per MDN Web Docs on Background Sync. Support is Chromium-based (Chrome, Edge) only; Safari and Android WebView don't implement it, so any offline-write flow needs a fallback path on those platforms (Web Background Synchronization (WICG spec), 2025).
One important constraint: the service worker's fetch event only intercepts requests from the same HTTPS origin. Cross-origin requests, CDN assets, third-party analytics, require explicit mode: 'cors' handling and opaque responses that Cache API stores but cannot inspect for validity. Teams consistently underestimate this on first implementation.
Web app manifest: The installability contract
The web app manifest is the installability contract between your PWA and the browser, a JSON file that declares how the app presents itself when installed on a device. Without a valid manifest, the add-to-home-screen prompt never fires, and the app shell architecture has nothing to anchor itself to.
Four fields gate installability in every current browser:
| Field | What it controls | Common mistake |
|---|---|---|
| name / short_name | App label on the home screen and splash screen | Missing short_name truncates on Android launchers |
| icons | Home screen and app-switcher icons | Omitting the 512×512 PNG fails the Lighthouse PWA audit |
| start_url | The URL that launches when the icon is tapped | Relative paths that resolve outside the service worker scope break offline launch |
| display | standalone, minimal-ui, fullscreen, or browser | Leaving it as browser disqualifies the install prompt entirely |
The W3C Web App Manifest specification defines display: standalone (or fullscreen) as a hard requirement for the install prompt, not a recommendation. Run a Lighthouse PWA audit with any of the four fields absent or malformed, and the "Installable" category fails outright, suppressing the prompt regardless of how well the service worker is written.
App shell architecture plugs in here directly. The start_url should point to the shell's entry point, the minimal HTML/CSS/JS frame cached during the service worker install event. That way, tapping the home screen icon launches from cache instantly, with dynamic content filling in once the network responds. A start_url that points to a fully server-rendered page breaks this pattern: the offline launch either fails or shows a blank screen. We saw this in practice with Powermeals: page speed improved from 9 to 2 seconds.
PWA installation flow: Prompt, manual, and store paths
PWA installation reaches users through three distinct paths, and which path fires depends entirely on the platform and browser, not on your code alone.
Browser-triggered prompt (Android/Chrome, Edge on Windows/macOS). When Chrome detects a valid web app manifest, a registered service worker, and an HTTPS origin, it queues the add-to-home-screen prompt automatically. You control when it surfaces by deferring the beforeinstallprompt event and triggering it at a high-intent moment, post-onboarding, after a third session, or when the user taps an explicit "Install app" button. This is the smoothest path: zero friction, no store listing required.
Manual A2HS (iOS Safari). Apple does not fire an automatic install prompt. On iOS, the user must tap the Share icon and select "Add to Home Screen" manually. The Web Push API became available on iOS 16.4+ (Apple WebKit release notes, 2023), which improved re-engagement after install, but the install discovery problem remains. For iOS-heavy audiences, in-app coach marks pointing to the Share icon are the practical workaround, not an API call.
Microsoft Store. Microsoft accepts PWAs for Store listing via PWABuilder. The web app manifest drives the Store metadata: name, icons, and screenshots fields populate the Store tile directly. This path adds discoverability without a separate native codebase.
| Path | Platform | Prompt auto-fires? | Store listing available? |
|---|---|---|---|
| beforeinstallprompt | Android, Edge/Windows | Yes | No |
| Manual A2HS | iOS Safari | No | No |
| Microsoft Store | Windows | N/A | Yes |
For most cross-platform PWAs, we recommend designing the install flow around the manual iOS path first, it's the most constrained, and treating the Chrome prompt as a progressive enhancement.
Real PWA outcomes: Twitter Lite, Starbucks, and B2B SaaS
PWA investments pay off fastest when the baseline experience is slow and the deployment pipeline is slow, two conditions that describe most B2B SaaS and high-traffic consumer apps simultaneously.
Twitter Lite is the canonical case. When Twitter rebuilt its mobile web experience using app shell architecture and Workbox-managed caching, the result was, according to case studies, a 65% increase in pages per session and a measurable drop in bounce rate on 2G/3G connections. The app shell architecture kept the chrome instantaneous while Workbox handled precaching of the timeline feed, the split that makes a PWA feel native on a slow radio.
Starbucks took a different angle: parity without an App Store dependency. Their PWA weighs roughly 233KB against a 148MB iOS native app, yet supports full menu browsing and order customization offline via Cache API. The Web Push API integration meant they could re-engage users who never installed the native app, a segment that had been unreachable before.
On the B2B side, the ROI case is less about engagement and more about maintenance overhead. Zeller, a financial services platform serving small businesses, is a clear example: after launching their PWA, more than 10,000 businesses signed up within the first eight months. The app shell architecture with a stale-while-revalidate caching pattern was central to that adoption rate, reducing time-to-interactive significantly and lowering the friction that typically stalls B2B onboarding on constrained networks.
Across these cases, the pattern is consistent: Web Push API expands the addressable audience, app shell architecture delivers perceived performance on constrained networks, and Workbox removes the service worker boilerplate that typically inflates build time. The specific numbers vary by context, but the structural advantages repeat reliably across consumer and B2B deployments alike.
PWA vs native app vs React Native: A decision table
React Native sits between a PWA and a fully native build on every axis that matters to a product decision: cost, device API surface, distribution overhead, and maintenance load. The table below maps all three options across the dimensions a CTO or engineering manager actually needs to compare.
| Dimension | PWA | React Native | Native (iOS/Android) |
|---|---|---|---|
| Time-to-market | Fastest, single codebase, no App Store review cycle | Medium, one codebase, store submission required | Slowest, two codebases, two review cycles |
| Maintenance overhead | Lowest, deploy via HTTPS origin, no store versioning | Medium, shared logic, platform-specific modules diverge over time | Highest, two release pipelines, two QA passes |
| Device API surface | Moderate: Web Push API, geolocation, camera, file system access; Bluetooth and NFC still limited | High, most device APIs available via community modules | Full, every SDK API, day-one hardware access |
| Store distribution | Not listed; add-to-home-screen prompt only | Listed on App Store and Google Play | Listed on App Store and Google Play |
| Offline capability | Strong, Cache API + service worker; requires deliberate caching strategy | Strong, React Native ships its own offline libs | Strong, native SQLite, background fetch |
| Lighthouse PWA audit | Required to validate installability and service worker compliance | Not applicable | Not applicable |
| SEO / discoverability | Indexed by search engines; URLs work | App Store only | App Store only |
| Initial build cost | Typically 30-50% less than equivalent native iOS+Android apps | $20,000-$300,000 depending on complexity, see React Native app development cost | Highest baseline |
Where PWAs lose. The device API gap is real. If your product needs Bluetooth peripherals, NFC payments, background audio, or ARKit/ARCore features, a PWA will hit a wall. The Web Push API now works on iOS 16.4+ iOS and iPadOS 16.4 added support for Web Push to web apps on Home Screen (WebKit Blog, 2023), closing the most-cited gap, but hardware-adjacent APIs remain thinner than what React Native can reach through its native module bridge.
Where PWAs win clearly. Content-heavy products, B2B tools, e-commerce storefronts, and internal dashboards rarely need device APIs beyond camera and location. For those, skipping the App Store distribution overhead, binary versioning, and dual QA cycle cuts both calendar time and ongoing engineering cost, two advantages that compound over a two-to-three year product lifecycle.
The React Native middle ground makes sense when you need store presence and hardware access but cannot staff or fund two native teams. React Native's tradeoff is that the shared JavaScript layer eventually diverges from platform behavior in ways that require native module work, the maintenance overhead starts low and drifts upward.
Our view: if store listing is not a hard requirement and your device API needs fit within the current web platform surface, a PWA delivers faster and costs less to maintain. Run a Lighthouse PWA audit on your existing web app first, the score often reveals whether the gap to full PWA compliance is a two-week sprint or a three-month re-architecture.
PWA limitations that still apply in 2026
PWAs close most gaps that existed before 2023, but four constraints still apply in 2026 and should factor into any go/no-go decision (Zylos Research - Progressive Web Apps: Bridging the).
Bluetooth and NFC remain out of reach. The Web Bluetooth API and Web NFC API are Chrome-only on Android; Safari does not expose either. A PWA built for contactless payments, medical device pairing, or retail scanner hardware will hit this ceiling immediately. The gap is not a versioning issue waiting for a patch: Apple's position on low-level hardware APIs has been consistent across multiple Safari releases, and there is no public roadmap signal suggesting change. If your core user flow depends on peripheral pairing or tap-to-transact hardware, native is the only viable call.
Web Push API on iOS still requires a deliberate opt-in path. iOS 16.4 introduced Web Push for PWAs installed to the home screen, and iOS 17 extended that support further. The constraint matters in practice, though, and deserves more than a footnote. First, the user must explicitly add the app to their home screen before the browser can surface a notification permission prompt at all.
Second, Safari on iOS still does not deliver push on the open web, meaning any user who simply bookmarks or stays in-browser receives nothing. Third, HTTPS is a hard prerequisite throughout. iOS 16.4 adds Web Push support for Home Screen web apps via Push API, Notifications API, and Service Workers (WebKit Blog - Web Push for Web Apps on iOS and 2023).
For engagement-heavy consumer products where push notifications drive retention, this multi-step funnel adds friction that native apps simply do not have. Teams should model expected install-to-permission rates against their actual iOS audience share before treating push as a reliable channel.
App Store discovery is absent by default. PWAs do not appear in the App Store or Google Play without a wrapper such as a Trusted Web Activity on Android. The add-to-home-screen prompt conversion rate is measurably lower than App Store install intent, though optimized messaging and strategic timing (prompting after 3+ pages or a first purchase, rather than on landing) can meaningfully lift acceptance rates (Progressive Web Apps 2026: Complete Development Guide).
Workbox reduces but doesn't eliminate caching complexity. Workbox abstracts service worker registration and cache strategies well, but background sync reliability on iOS remains inconsistent across app suspensions. Teams should verify Background Sync API behavior on Safari before committing to offline-first write patterns.
Go / no-go framework: Should you build a PWA?
Build a PWA when your connectivity needs, timeline, and device API surface all point the same direction. The grid below maps the four constraints that should drive the decision, not preference, not trend.
| Criterion | Build PWA | Build Native |
|---|---|---|
| Connectivity | Offline read/write via Background Sync API matters, but full offline-first isn't required | Hard offline-first with complex local sync |
| Device APIs | Push notifications, camera, geolocation, payments sufficient | Bluetooth, NFC, ARKit, background location |
| Budget / timeline | Single codebase, faster to market | Separate iOS/Android teams acceptable |
| Distribution | Search-discoverable, add-to-home-screen prompt enough | App Store presence required for trust or monetization |
Run a Lighthouse PWA audit before committing: it surfaces HTTPS origin requirement gaps, missing web app manifest fields, and service worker install event failures that kill installability before a line of product code ships. In our experience, projects that adopt app shell architecture from week one pass Lighthouse installability checks without remediation sprints. Projects that bolt it on later spend two to three weeks retrofitting.
PWA FAQ
What is required for a web app to be PWA-ready?
What is a service worker in a PWA?
What is a web app manifest file in a PWA?
What is an example of a PWA in 2026?
PWA vs native app, which should I build?
What is PWA browser support on iOS safari in 2026?
How do users install a progressive web app?
How do PWA and React Native performance tradeoffs compare?
Ready to audit or build your PWA?
If a Lighthouse PWA audit flags missing service worker registration or manifest gaps in your current web app, those are fixable in days, not months. The harder question is whether your product's use case justifies the investment, and that's where a structured audit pays for itself before a single line of code changes.
Our team has run PWA audits and builds across fintech, marketplace, and retail products, from greenfield builds to page-speed and performance rebuilds. If you want a candid assessment of your current architecture, not a sales pitch, talk to our team and we'll scope a discovery conversation around your specific constraints.
