How to Create Progressive Web Apps (PWA)

PWA Create a Progressive Web App

Clarity TLDR: A PWA is a regular website plus two files: a web app manifest (makes it installable) and a service worker (makes it work offline). Everything else — HTTPS, responsive design, fast loading — is just a well-built site. Both files, ready to copy, are below.

Most “How to create a PWA” tutorials bury you in concepts before showing a single line of code. This one shows the code first, because that’s all a PWA structurally is: your existing site, served over HTTPS, with a manifest file and a service worker.

What is a Progressive Web App?

A Progressive Web App (PWA) is a website that browsers can install and launch like a native app, with an icon on the home screen, its own window (no browser chrome), and the ability to work offline. It’s built with ordinary HTML, CSS, and JavaScript — no app store, no separate codebase for Android and iOS.

What does a site need to qualify as a PWA?

  • Served over HTTPS — service workers only run on secure connections.
  • A web app manifest — a JSON file describing the app’s name, icons, and colors.
  • A registered service worker — JavaScript that controls caching and offline behavior.
  • At least one 192×192 and one 512×512 icon for the manifest.

That’s the entire checklist. If you have those four things, browsers treat your site as installable.

Step 1: Add the web app manifest

Create a file called manifest.json in your site root:

{
  "name": "My App — Full Name",
  "short_name": "MyApp",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#1e6fd9",
  "icons": [
    { "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" }
  ]
}

Then link it in your page’s <head>:

<link rel="manifest" href="/manifest.json">

display: "standalone" is what makes the installed app open in its own window instead of a browser tab. short_name is the label under the home-screen icon.

Step 2: Add the service worker

Create sw.js in your site root. This minimal version caches your core assets on first visit and serves them offline afterward:

// sw.js — minimal cache-first service worker
const CACHE = "myapp-v1";
const ASSETS = ["/", "/css/style.css", "/js/app.js", "/icons/icon-192.png"];

self.addEventListener("install", e => {
  e.waitUntil(caches.open(CACHE).then(c => c.addAll(ASSETS)));
});

self.addEventListener("fetch", e => {
  e.respondWith(
    caches.match(e.request).then(cached => cached || fetch(e.request))
  );
});

Then register it from your page — this can go in your existing JS or a small inline script:

if ("serviceWorker" in navigator) {
  navigator.serviceWorker.register("/sw.js");
}

One rule to remember: the service worker can only control pages at or below its own path. Put sw.js in the root and it covers your whole site.

Step 3: Verify it’s installable

Open Chrome DevTools → Application tab → Manifest. If there are no errors and the install criteria are met, Chrome will show an install prompt — and the address bar will show an install icon. If DevTools says “no matching service worker,” check that sw.js is registered and served from the root over HTTPS.

Step 4: Test with Lighthouse

Run the Lighthouse audit (DevTools → Lighthouse tab, or npx lighthouse https://yourdomain.com). Google’s PWA criteria are checked automatically. Don’t chase a 100 score — the install and offline checks are what matter for PWA functionality.

Do you need React, Angular, or Vue?

No. PWAs are framework-agnostic because the manifest and service worker are plain files served alongside whatever your site is built with. Use a framework if you already use one. If your caching needs grow beyond a few files, look at Workbox — Google’s library that generates service workers for you.

The whole thing, in one paragraph

Add manifest.json, link it in your head, add sw.js, register it, serve over HTTPS. That’s a PWA. Everything beyond that is normal web development.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.