What Is a PWA? Progressive Web Apps Explained
A PWA is a website built to behave like a native app — installable, offline-capable, and fast — using standard web technologies, not app-store code.
A progressive web app, or PWA, is a website built with enough capability to behave like a native app: it can be installed to a home screen, work offline, send push notifications, and load instantly on repeat visits — all using standard web technologies, without an app-store submission or a separate native codebase. “Progressive” refers to the core idea: the app works as a normal website for anyone, and progressively enhances itself with app-like behavior for browsers and devices that support the underlying APIs.
The three technical pillars
A PWA isn’t a single API — it’s a pattern built from a few specific web platform features working together.
A service worker. This is the foundation. A service worker is a script that runs separately from the page, sitting between your app and the network, able to intercept requests and decide whether to serve them from a cache, from the network, or some combination of both. This is what makes offline functionality and instant repeat loads possible — without a service worker, there’s no PWA, just a website with a manifest file.
A web app manifest. A JSON file that describes the app to the operating system: its name, icons, theme color, and how it should launch (full-screen, in a browser tab, with or without the browser’s address bar). This is what lets a browser offer an “install” prompt and what makes the installed app look and launch like any other app on the device, rather than opening as a bookmarked tab.
HTTPS. PWAs require a secure origin. This isn’t incidental — service workers can intercept and modify every network request the page makes, which is powerful enough that browsers restrict the capability to origins that can prove they haven’t been tampered with in transit. See what HTTPS actually does for why that guarantee matters here specifically.
What “installable” actually means
Installing a PWA doesn’t involve an app store, a build pipeline that produces a platform-specific binary, or a review process. The browser packages the existing web app — the same HTML, CSS, and JavaScript already running in the tab — and adds an icon to the home screen or app launcher that opens it in a standalone window, governed by the manifest’s display settings. There’s no separate codebase to maintain for “the app version” versus “the website version,” because they’re the same code.
This is the core trade-off PWAs make relative to native apps: broader reach and a single codebase, in exchange for reduced access to some device-level APIs and platform-specific capabilities that remain native-app-only on some operating systems.
Offline behavior and caching strategy
The service worker’s caching strategy determines how a PWA behaves without a network connection, and different parts of an app usually want different strategies:
- Cache-first — serve from the cache immediately, only hitting the network if nothing is cached. Good for static assets — fonts, icons, app shell HTML — that rarely change.
- Network-first — try the network, fall back to cache if it fails. Good for content that should be fresh when possible but still usable offline, like an article or a dashboard.
- Stale-while-revalidate — serve the cached version immediately for speed, then fetch an updated version in the background to use next time. A common middle ground for content that changes but doesn’t need to be perfectly current on every load.
Getting this right is a meaningful part of what separates a PWA that feels genuinely reliable offline from one that just silently fails to load when the network drops. It’s closely related to the ideas behind local-first software, which pushes the same offline-capable philosophy further by treating the local device, not the server, as the primary source of truth.
Why performance and PWA quality are linked
A PWA that’s slow to load the first time undermines its own pitch — the whole point is app-like responsiveness. This ties PWA work directly into general Core Web Vitals performance work: a lean app shell, efficient caching, and fast time-to-interactive all matter both for search and UX metrics generally and specifically for whether a PWA feels like a real app rather than a slow website wearing an icon. Smooth transitions between views — something the View Transitions API was built to support natively — also contribute meaningfully to that native-app feel, reducing the jarring full-page-reload sensation that used to be a giveaway that you were still “just in a browser.”
PWA vs native app
| PWA | Native app | |
|---|---|---|
| Codebase | One, using web technologies | Typically separate per platform |
| Distribution | Direct install from the browser, or app stores on some platforms | App store submission and review |
| Offline support | Yes, via service worker caching | Yes, built in from the start |
| Device API access | Growing, but narrower than native | Full platform API access |
| Update process | Instant — same as deploying a website | Store review and user update cycle |
The takeaway
A PWA is a website engineered to earn app-like behavior — installability, offline access, fast repeat loads — through a service worker, a manifest, and HTTPS, without forking into a separate native codebase. It’s not a replacement for native apps in every case, particularly where deep device API access matters, but for a large share of app-like use cases it offers a single codebase, instant updates, and reach that a store-gated native app can’t match. Getting there mostly comes down to the same fundamentals: a well-designed service worker caching strategy and genuine attention to load performance.
Keep reading
Takina · · 4 min read What Is the Beacon API? navigator.sendBeacon()
The Beacon API lets a page send one last async request as it unloads, without blocking navigation or racing the browser's page teardown.
Takina · · 3 min read What Is Fetch Priority? The fetchpriority Attribute
fetchpriority lets you tell the browser which resources matter most, overriding its default heuristics to load critical assets sooner.
Takina · · 5 min read CSS will-change Explained: Compositing and Performance
The CSS will-change property hints the browser to prepare an element for an upcoming change, moving it to its own compositor layer. When to use it and when not to.