Progressive Web App Fundamentals¶
A Progressive Web App (PWA) is a website that uses a small set of standard web platform features (a secure context, a Web App Manifest and, usually, a service worker) to behave like an installed application: it can launch from the home screen or dock, open in its own window, keep working on a flaky network and integrate with the operating system. This section gives you the conceptual foundation for everything else on the site: what a PWA is and is not, where the idea came from, how it compares to native and hybrid apps, which building blocks it is made of, what browsers require before they offer installation, and a hands-on tutorial that ties it together.
Key takeaways
- A PWA is not a framework, a file format or a store listing. It is an ordinary website that progressively gains app capabilities as the browser and the user allow.
- The three pillars are capable (access to device and OS features), reliable (fast and resilient regardless of network) and installable (a first-class launcher icon and window).
- Technically, three things carry the load: a secure context (HTTPS), a Web App Manifest that describes the app, and a service worker that sits between your pages and the network.
- Installability rules differ per browser, and they have become less strict over time. Safari on iOS 26 and macOS lets users add any site as a web app, and Chrome no longer requires a service worker to install.
- Read What Is a PWA? first, then either the tutorial (hands-on) or Core Building Blocks (conceptual), depending on how you learn.
What this section covers¶
The Fundamentals section is deliberately conceptual. Deep API references live in the Core Technologies, Capabilities and Engineering sections; here you build the mental model you need to use those references well. Each page answers one question in depth:
| Page | The question it answers | Read it when |
|---|---|---|
| What Is a PWA? | What exactly counts as a PWA, technically and historically? What can and can't it do? | You need a precise definition or have to explain PWAs to someone else |
| History & Evolution | How did the web get from 2007 iPhone web apps to the 2026 Web Install API, and why did AppCache fail? | You want context for today's design decisions and platform politics |
| PWA vs Native vs Hybrid | When is a PWA the right delivery model, and what are the real trade-offs? | You are choosing an architecture or defending one |
| Core Building Blocks | How do the manifest, service worker, caches, storage and HTTPS fit together? | You want the system view before diving into individual APIs |
| Installability Criteria | What does each browser require before it offers "Install", and how do you debug a missing prompt? | Your app does not install, or you need to support a new platform |
| Tutorial: Your First PWA | How do you build a complete, installable, offline-capable PWA from an empty folder? | You learn best by building |
The three pillars: capable, reliable, installable¶
Most descriptions of PWAs reduce them to three adjectives. They are only useful if you know which concrete mechanisms sit behind each one, and how you would measure them.
Capable: the web platform can reach the device¶
"Capable" means your app can do the things users expect from an application, not just from a document: share content to other apps, receive shared files, open files from the OS file manager, read and write local files, show notifications, set an icon badge, talk to Bluetooth or USB hardware, handle a custom URL protocol, take payments and sign in with passkeys.
The mechanism is a large family of individual web APIs, most of which are gated by three layers of protection:
- Secure context. Nearly every powerful API is only exposed on HTTPS (or
localhost). Check it withwindow.isSecureContext. - User activation or permission. APIs such as
navigator.share()require a recent user gesture (transient activation); APIs such as notifications or Bluetooth require an explicit permission grant. - Install state or display mode. Some capabilities only exist for installed apps: Web Push on iOS and iPadOS requires the site to be added to the Home Screen, Periodic Background Sync in Chromium requires installation, and manifest-declared integrations such as
file_handlers,share_targetorprotocol_handlersonly take effect once the OS knows about the app.
Capability support is uneven. Many APIs come from the cross-company Capabilities project (Project Fugu) and ship only in Chromium-based browsers; others, like Web Share, the Badging API and Web Push, are available in Safari too. The Device & OS Integration and Background & Engagement sections give per-API support tables.
Reliable: fast and resilient on any network¶
"Reliable" means the app starts quickly and behaves predictably whether the network is fast, slow, flaky or absent. The central mechanism is the service worker: a script the browser runs in a separate worker thread, outside any page, that receives a fetch event for every request made by the pages it controls. Because it can answer those requests from the Cache Storage API, from IndexedDB or from generated responses, it can:
- load the app shell instantly from a local cache, independent of network latency;
- show a meaningful offline page or cached content instead of the browser's error page;
- serve stale content immediately and update it in the background;
- queue writes made while offline and replay them later (with Background Sync where available, or on the next launch elsewhere).
Reliability is measurable: time-to-first-render on repeat visits, the percentage of navigations served from cache, and whether every route renders something useful when you toggle "Offline" in DevTools. The Caching & Offline section covers the strategies in depth.
Installable: a first-class place on the device¶
"Installable" means the user can add the app to their home screen, app launcher, dock, taskbar or Start menu, and launch it into its own window without browser UI. The mechanism is the Web App Manifest, a JSON file linked from your pages with <link rel="manifest">, which supplies the name, icons, start URL, scope, display mode and theme colors the OS needs to create an app entry.
What "installed" means varies by platform: on Android, Chrome mints a WebAPK (a real Android package); on desktop Chromium, the browser registers an app with the OS; on iOS and iPadOS, the system creates a Home Screen web app backed by WebKit; on macOS, Safari creates a Dock app. The Installation section and the Installability Criteria page have the platform-by-platform details.
The pillars are independent
You can ship any pillar without the others. A service worker that only adds offline support is worth having even if nobody installs your app, and an installable app with no service worker is valid in every current browser. Treat the pillars as a checklist of user benefits, not as an all-or-nothing certification.
The mental model: a website that progressively gains app capabilities¶
The word progressive is the most important part of the name. A PWA starts life as a normal website that works in every browser and every context: a link from search, a shared URL, a tab. It then layers on capabilities only where the browser supports them and only when the user opts in. Alex Russell's 2015 essay that introduced the term put it this way: sites "have to earn that right over time as you use them more and more. They progressively become 'apps'."
A useful way to reason about your own project is as a ladder in which each rung is optional and builds on the previous one:
| Rung | What you add | What users get | Where a browser without support ends up |
|---|---|---|---|
| 0 | Semantic HTML, responsive CSS, working links | A usable site on any device | Nothing to fall back from |
| 1 | HTTPS everywhere | Integrity, privacy, access to powerful APIs | Nothing to fall back from; HTTPS is universal |
| 2 | A Web App Manifest | Install to home screen, dock or Start menu; standalone window; themed UI | The manifest is ignored; the site stays a site |
| 3 | A service worker with an offline fallback | A branded offline page instead of the browser error | The site behaves exactly as before |
| 4 | Precaching the app shell and runtime caching | Instant repeat loads, offline reading | Normal network loading |
| 5 | Push, badging, background sync | Re-engagement and background work | Features are hidden via feature detection |
| 6 | OS integration (share target, file and protocol handlers, shortcuts) | The app behaves like a native citizen of the OS | Manifest members are ignored |
The practical consequence: you never write if (isPWA). You write if ("serviceWorker" in navigator), if ("setAppBadge" in navigator), if (window.matchMedia("(display-mode: standalone)").matches) and so on. Every capability is detected individually, and the baseline experience never depends on any of them.
// Each rung of the ladder is detected and enabled independently.
// Nothing here is required for the site to work.
if ("serviceWorker" in navigator && window.isSecureContext) {
navigator.serviceWorker.register("/sw.js").catch((error) => {
// A failed registration must never break the page. Log and move on.
console.warn("Service worker registration failed:", error);
});
}
if ("setAppBadge" in navigator) {
// Badging API: Chromium desktop and installed web apps in Safari.
document.documentElement.classList.add("can-badge");
}
const standalone = window.matchMedia("(display-mode: standalone)");
const applyDisplayMode = () =>
document.documentElement.classList.toggle("is-standalone", standalone.matches);
applyDisplayMode();
standalone.addEventListener("change", applyDisplayMode);
The What Is a PWA? page expands this into a complete feature-detection module.
Architecture at a glance¶
Every PWA, from a static blog to a large single-page application, has the same four moving parts: the page (your documents and their JavaScript), the manifest (static metadata read by the browser and the OS), the service worker (an event-driven script that controls pages within its scope) and storage (Cache Storage for HTTP responses, IndexedDB for structured data, and the Origin Private File System for files). The diagram shows how they relate.
flowchart LR
User(["User"]) --> OS["OS launcher, dock or home screen"]
OS -->|"launches start_url"| Page
subgraph Browser["Browser engine"]
Page["Page: HTML, CSS, JS"]
SW["Service worker"]
Caches[("Cache Storage")]
IDB[("IndexedDB and OPFS")]
end
Manifest["manifest.webmanifest"] -->|"name, icons, scope, display"| Browser
Browser -->|"install"| OS
Page -->|"register /sw.js"| SW
Page -->|"fetch requests"| SW
SW -->|"cache hit"| Caches
SW -->|"cache miss or refresh"| Network[("Network and origin server")]
Page --> IDB
SW --> IDB
PushService["Push service"] -->|"push event"| SW How to read it:
- The manifest flows to the browser, and the browser informs the OS. Your code never talks to the OS launcher directly. The browser reads the manifest, decides whether and how the app can be installed, and creates the OS-level entry (a WebAPK, an app shortcut, a Dock app, a Home Screen web app).
- The page registers the service worker, but the service worker controls the page. After registration and activation, every request made by a controlled page (including the navigation request for the next page) is dispatched as a
fetchevent to the service worker, which decides whether to answer from Cache Storage, from the network, or by constructing a response. - Both the page and the service worker share the origin's storage. Cache Storage and IndexedDB are available in windows and workers alike, which is how a page can pre-populate data the service worker later serves offline.
- The push service talks only to the service worker. Push messages are delivered by the browser vendor's push service (Firebase Cloud Messaging for Chrome, Apple Push Notification service for Safari, Mozilla's autopush for Firefox) to the service worker, which can run even when no page is open. Safari's Declarative Web Push can even display a notification without running any service worker code.
Once you have this picture, the rest of the site maps onto it cleanly: Web App Manifest covers the left side, Service Workers the middle, and Caching & Offline the storage on the right. The Core Building Blocks page walks through each box and arrow in detail.
Recommended reading paths¶
Different readers need different entry points. Pick the path that matches your situation; each one ends with enough knowledge to ship a production PWA.
If you are new to PWAs¶
- What Is a PWA?: definitions, the original characteristics, a minimal working example and the misconceptions to avoid.
- Core Building Blocks: the system view of manifest, service worker, caches and HTTPS.
- Tutorial: Your First PWA: build and install a real app step by step.
- Installability Criteria: understand why a browser does or does not offer installation.
- Service Worker Lifecycle and Caching Strategies: the two topics that cause the most production bugs.
- Installation by Platform: what users on each OS actually see.
If you already ship web apps¶
- Skim What Is a PWA?, focusing on "How an installed PWA actually runs" and "Hard limits".
- Read Installability Criteria for the current per-browser rules; they changed substantially in 2023–2025.
- Go straight to Service Workers, especially Updating Service Workers and Pitfalls & Anti-Patterns.
- Review iOS & iPadOS for Safari-specific behavior.
- Finish with the Production Checklist.
If you are evaluating PWAs for a product decision¶
- PWA vs Native vs Hybrid for the trade-offs.
- When to Build a PWA for decision criteria.
- History & Evolution for context on platform support trajectories, including the 2024 EU Digital Markets Act episode on iOS.
- Case Studies for sourced, real-world results.
- Publishing to App Stores if store presence is a requirement.
Pages in this section¶
-
What Is a PWA?
The precise definition, the 2015 origin of the term, the ten characteristics explained technically, a complete minimal PWA and the common misconceptions.
-
History & Evolution
From iPhone web apps, Google Gears and AppCache through service workers, Project Fugu and the DMA episode to Declarative Web Push and the Web Install API.
-
PWA vs Native vs Hybrid
Capabilities, distribution, performance, cost and maintenance compared, with a decision framework.
-
Core Building Blocks
How HTTPS, the Web App Manifest, the service worker, Cache Storage and IndexedDB work together as one system.
-
Installability Criteria
Exactly what Chrome, Edge, Samsung Internet, Safari and Firefox require before offering installation, and how to debug a missing prompt.
-
Tutorial: Your First PWA
Build an installable, offline-capable app from an empty folder, with production-grade service worker code.
Where to go next¶
Once the fundamentals are in place, the rest of the site is organized around the four areas you will work in day to day.
-
Core Technologies: Web App Manifest
Every manifest member, icons and maskable icons, display modes, app identity and updates, shortcuts and rich install UI.
-
Core Technologies: Service Workers
Lifecycle, registration and scope, fetch handling, updates, navigation preload, messaging and static routing.
-
Core Technologies: Caching & Offline
Cache Storage, strategies, precaching, offline UX, HTTP caching interplay, quotas, IndexedDB and OPFS.
-
Capabilities: Background & Engagement
Push notifications and the Web Push protocol, iOS web push, badging, background sync and background fetch.
-
Capabilities: Device & OS Integration
Web Share and Share Target, file system and file handling, protocol handlers, Window Controls Overlay, hardware APIs, payments and passkeys.
-
Install & Distribute
Install prompts, detecting installed apps, per-platform behavior, app stores, Trusted Web Activity and platform support notes.
-
Engineering: Performance & Architecture
App shell, Core Web Vitals, loading and runtime performance, SPA vs MPA, offline-first data and streaming.
-
Engineering: Tooling, Testing & Security
Workbox, Vite PWA, framework integrations, DevTools, automated tests, Lighthouse, CSP and service worker security.
Vocabulary used throughout this site¶
The same things are called by different names on different platforms, which causes real confusion in bug reports and specifications. This site uses the following terms consistently; the Glossary has the complete list.
- Installed web app
- The generic term for a web app that has an OS-level launcher entry and opens in its own window. "PWA" in this site's prose usually means the same thing, with the added expectation that the app was designed to be installed.
- Home Screen web app
- Apple's term for a site added to the Home Screen on iOS or iPadOS that opens as a web app rather than as a Safari tab. Since iOS 26, every site added to the Home Screen opens this way by default unless the user turns off "Open as Web App".
- WebAPK
- An Android package that Chrome (on devices with Google Play services) and Samsung Internet generate for an installed PWA, so the app appears in the launcher, in Android settings and can register intent filters for its URLs.
- Standalone
- The
displaymode in which the app has its own window without browser navigation UI. Detect it with the(display-mode: standalone)media query. Safari additionally exposes the legacy non-standardnavigator.standaloneboolean on iOS and iPadOS and, since Safari 17, on macOS (truein Dock web apps); check it first on Apple platforms, because an iOS web app whose manifest saysstandalonematches(display-mode: fullscreen). - Scope
- The URL prefix that belongs to the app. It exists twice: the manifest scope (which navigations stay inside the app window) and the service worker scope (which pages the worker controls). They are independent and frequently confused.
- Controlled page
- A document whose requests are routed through a service worker. A page is only controlled if a service worker was active for its scope when the navigation started, or if the worker called
clients.claim(). - App shell
- The minimal HTML, CSS and JavaScript needed to render the application's chrome, cached so that the UI appears instantly while content loads. See App Shell Model.
Further reading¶
On this site
- What Is a PWA?
- History & Evolution
- Core Building Blocks
- Installability Criteria
- Tutorial: Your First PWA
- Service Worker Lifecycle
- Glossary
External references