Frontend Engineering/
Lesson

Twitter, Starbucks, and Pinterest all ship PWAs alongside (or instead of) native apps. Why? Because a Progressive Web AppWhat is pwa?A web app enhanced with browser APIs so it can install on a device, work offline, and send push notifications like a native app. gives you offline support, home screen installation, and push notifications without needing the App Store. If you already know how to build a website, you're most of the way there.

What makes a web app "progressive"

The word "progressive" doesn't mean the app is fancy, it means it works for every user, in every context, and then improves when the browser supports more features. Someone on an older phone with a slow connection still gets a working experience. Someone on a modern device with a fast connection gets the full-featured version.

Three qualities define a PWAWhat is pwa?A web app enhanced with browser APIs so it can install on a device, work offline, and send push notifications like a native app.:

Capable

A capable PWA can do things that used to require a native app. It works offline or on a flaky connection, can access device features like the camera and geolocation, and loads quickly because it aggressively caches resources. The browser APIs that make this possible, Cache APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses., IndexedDBWhat is indexeddb?A database built into the browser that stores structured data, supporting large datasets and offline-first apps., Push, Background SyncWhat is background sync?A Service Worker API that queues network requests made while offline and replays them automatically when connectivity is restored., are now well-supported across Chrome, Firefox, Safari, and Edge.

Reliable

Reliability means the app always responds, even when the network doesn't. No white screen, no spinner that spins forever. When a user opens your PWA without internet, a cached version loads instantly. This is one of the biggest wins over a regular website and it's the reason Service Workers exist.

Engaging

An engaging PWA feels like a real app. It installs to the home screen, launches in its own window without a browser address bar, and can send push notifications when the user isn't actively using it. That install moment, when Android or iOS prompts the user to "Add to Home Screen", is what closes the gap between web and native.

02

Why ship a PWAWhat is pwa?A web app enhanced with browser APIs so it can install on a device, work offline, and send push notifications like a native app. instead of a native app

You don't have to choose one or the other, but here's why teams increasingly prefer PWAs for their primary distribution channelWhat is channel?A typed conduit in Go used to pass values between goroutines - can be unbuffered (synchronous) or buffered (async queue).:

FactorNative appPWA
DistributionApp Store / Play Store reviewDirect URL
UpdatesUser must download updateInstant, automatic
Bundle size10–100 MB typicalA few hundred KB
PlatformsSeparate iOS and Android buildsOne codebase
SEONoneFull indexing
Install frictionStore account requiredOne tap
The flip side
PWAs still have access limitations on iOS (no push notifications until iOS 16.4, limited background sync). If you need deep system integration, a native layer is still worth it.
03

The three files every PWAWhat is pwa?A web app enhanced with browser APIs so it can install on a device, work offline, and send push notifications like a native app. needs

You can turn almost any existing website into a PWA by adding three things:

  1. A manifest.json, describes your app to the browser
  2. A sw.js, your Service WorkerWhat is service worker?A background script the browser runs separately from your web page that intercepts network requests, enabling offline support and caching. script
  3. A registration snippet, tells the browser where to find the Service Worker

That's it. The restWhat is rest?An architectural style for web APIs where URLs represent resources (nouns) and HTTP methods (GET, POST, PUT, DELETE) represent actions on those resources. is progressive enhancementWhat is progressive enhancement?Building a feature so it works without JavaScript first, then adding richer behavior when JavaScript is available in the browser. on top of a normal web app.

<!-- index.html: the minimum to make a PWA installable -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My PWA</title>

  <!-- 1. Link the manifest -->
  <link rel="manifest" href="/manifest.json">

  <!-- 2. Set the theme color (browser chrome on mobile) -->
  <meta name="theme-color" content="#6366f1">

  <!-- 3. iOS doesn't read the manifest for the touch icon -->
  <link rel="apple-touch-icon" href="/icon-192.png">
</head>
<body>
  <div id="app">
    <h1>My Progressive Web App</h1>
  </div>

  <!-- 4. Register the Service Worker -->
  <script>
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/sw.js')
        .then(reg => console.log('SW registered, scope:', reg.scope))
        .catch(err => console.error('SW registration failed:', err));
    }
  </script>
</body>
</html>
04

Key technologies at a glance

TechnologyWhat it does
Service WorkerBackground script, caching, offline, push
Web App ManifestJSON that defines name, icons, display mode
Cache APIStore request/response pairs for offline use
IndexedDBClient-side database for structured data
HTTPSRequired for Service Workers to register

In the next lesson you'll dig into Service Workers, the piece that makes everything else possible.

05

Quick reference

FilePurpose
manifest.jsonApp identity and install behavior
sw.jsService Worker, runs in background
index.htmlLinks the manifest, registers the SW
offline.htmlFallback page shown when network fails
javascript
// Minimal PWA structure

// 1. index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My PWA</title>

  <!-- Link to manifest -->
  <link rel="manifest" href="/manifest.json">

  <!-- Theme for mobile -->
  <meta name="theme-color" content="#6366f1">

  <!-- Icons -->
  <link rel="icon" type="image/png" sizes="192x192" href="/icon-192.png">
  <link rel="apple-touch-icon" href="/icon-192.png">
</head>
<body>
  <div id="app">
    <h1>My Progressive Web App</h1>
    <p id="status">Status: <span>Online</span></p>
  </div>

  <!-- Service Worker registration -->
  <script>
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/sw.js')
        .then(reg => console.log('SW registered'))
        .catch(err => console.log('SW error', err));
    }
  </script>
</body>
</html>

// 2. manifest.json
{
  "name": "My Super PWA",
  "short_name": "PWA",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#6366f1",
  "orientation": "portrait",
  "icons": [
    {
      "src": "/icon-192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/icon-512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}