Skip to main content

Progressive Web Apps

What It Is

A Progressive Web App, also called PWA, is a web application built with standard web technologies like HTML, CSS, and JavaScript.

It is designed to feel like a native app by supporting installation, offline usage, fast loading, and app-like behavior across devices.

PWA = Website + App-like experience + Offline support + Installability

Why It Is Called Progressive

The word progressive means the app should work for every user regardless of browser support.

If a browser supports advanced features, the app can provide a richer experience.

If not, the basic web experience should still work.

Basic browser -> normal website
Modern browser -> installable offline-capable app

This idea is based on progressive enhancement.


Core Requirements

A PWA commonly uses these main pieces.

RequirementPurpose
HTTPSRequired for installability and secure powerful APIs
Service WorkerEnables offline behavior and cache/network control
Web App ManifestDescribes the app for installation

Modern installability mainly depends on HTTPS and a valid web app manifest. A service worker is still commonly used for offline support, but current browser install criteria do not always require it.


How PWA Installation Works

When the PWA requirements are satisfied, the browser can show an install prompt.

The user can add the app to:

  • mobile home screen
  • desktop
  • app launcher

After installation, the app can open in its own window without the normal browser address bar.

Install prompt -> User installs -> App opens like native app

Service Worker Role

The service worker is the main piece that enables offline behavior.

Without a service worker:

Browser -> Server

With a service worker:

Browser -> Service Worker -> Cache / Network

The service worker decides whether a request should be served from cache or fetched from the internet.

This gives control over offline behavior and faster repeat visits.


Advantages

PWAs provide many user and business benefits.

AdvantageMeaning
Offline supportWorks without internet using cached assets
InstallableCan be added to home screen or desktop
Fast loadingCached assets reduce latency
ResponsiveWorks across mobile, tablet, and desktop
No app store requiredDistributed using a URL
Auto-updatesService worker can update in the background
Push notificationsCan re-engage users using Web Push API
Lower development costOne codebase gives web and app-like experience
SEO friendlyDiscoverable and indexable by search engines
Reduced data usageCache-first strategy saves bandwidth on repeat visits

Disadvantages

PWAs also have limitations.

DisadvantageMeaning
Limited iOS supportSome PWA features are restricted on Apple platforms
Restricted native APIsSome device APIs may not be available
Less discoverableUsers may not find it like App Store or Play Store apps
Storage pressureBrowser may clear cache when device storage is low
Complex debuggingOffline behavior and service worker state can be harder to debug
No app store presenceSome users may trust store apps more

Basic Project Structure

A minimal PWA uses multiple files together.

project/
index.html -> Main HTML file
style.css -> Application styles
script.js -> Registers the service worker
sw.js -> Service worker file
manifest.json -> App metadata for installation

Each file has a specific role.

FilePurpose
index.htmlLinks manifest and loads app scripts
script.jsRegisters the service worker
sw.jsHandles install, fetch, cache, and activate events
manifest.jsonDefines app name, icons, colors, display mode, and launch URL

Registering the Service Worker

The service worker file does not run automatically.

It must be registered from the main JavaScript file, usually script.js.

if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
navigator.serviceWorker
.register("./sw.js")
.then((reg) => {
console.log("Service Worker registered:", reg);
})
.catch((err) => {
console.error("Registration failed:", err);
});
});
}

This code checks whether the browser supports service workers and registers sw.js after the page loads.

script.js -> registers sw.js -> service worker can install and handle fetches

Service Worker Install Event

The install event runs once when the service worker is first installed.

Its main job is to pre-cache important files so the app can work offline later.

const CACHE_NAME = "pwa-demo-v1";

const ASSETS = ["./index.html", "./style.css", "./script.js", "./sample.jpg"];

self.addEventListener("install", (event) => {
console.log("Service Worker installing...");

event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
console.log("Caching core assets...");
return cache.addAll(ASSETS);
}),
);
});

event.waitUntil() tells the browser to wait until caching finishes before completing installation.

Install event = prepare important assets for offline usage

Service Worker Fetch Event

The fetch event runs for every network request made by the page.

The example uses a Cache First strategy.

self.addEventListener("fetch", (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
if (response) {
console.log("Serving from cache:", event.request.url);
return response;
}

return fetch(event.request).catch(() => {
return caches.match("./index.html");
});
}),
);
});

The flow is:

Check cache first
If found -> return cached response
If missing -> fetch from network
If network fails -> return offline fallback

This strategy works well for static assets like CSS, JS bundles, logos, and images.


Service Worker Activate Event

The activate event runs when a new service worker becomes active.

Its main job is to remove old cache versions.

self.addEventListener("activate", (event) => {
console.log("Service Worker activating...");

event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames
.filter((name) => name !== CACHE_NAME)
.map((name) => {
console.log("Deleting old cache:", name);
return caches.delete(name);
}),
);
}),
);
});

This prevents old assets from staying in the browser cache.

Activate event = clean old cache versions

Linking Manifest in HTML

The manifest file must be linked inside the head of index.html.

The page should also include a theme color.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<meta name="theme-color" content="#4F46E5" />

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

<title>My PWA App</title>

<link rel="stylesheet" href="./style.css" />
</head>

<body>
<!-- app content -->

<script src="./script.js"></script>
</body>
</html>

This connects the web page with the app manifest and service worker registration script.


Web App Manifest

The Web App Manifest is a JSON file that tells the browser how the PWA should behave when installed.

It controls:

  • app name
  • short name
  • description
  • start URL
  • display mode
  • theme color
  • background color
  • orientation
  • scope
  • icons

Manifest Example

{
"name": "Namaste Frontend System Design",
"short_name": "Namaste",
"description": "Offline-first PWA demonstrating system design concepts",
"start_url": "./index.html",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#4F46E5",
"orientation": "portrait-primary",
"scope": "/",
"icons": [
{
"src": "./icons/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "./icons/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}

Manifest Fields

FieldMeaning
nameFull app name shown on splash screen and OS app list
short_nameShort label used on home screen icons
descriptionBrief description used by some browsers and search engines
start_urlURL opened when the app launches
displayControls how much browser UI is visible
background_colorSplash screen background before CSS loads
theme_colorBrowser toolbar or status bar color
orientationLocks orientation such as portrait, landscape, or any
scopeURL area controlled by the app
iconsApp icons in different sizes

Display Modes

The display field controls how the installed app opens.

ModeMeaning
standaloneLooks like a native app without address bar
fullscreenUses the full screen, useful for immersive apps
minimal-uiShows minimal browser controls
browserOpens like a normal website in a browser tab

Most PWAs commonly use:

{
"display": "standalone"
}

Icon Best Practices

A PWA should include proper icons for installation.

Important practices:

  • provide at least 192x192 and 512x512 PNG icons
  • use purpose: "maskable" for adaptive Android icons
  • use purpose: "any" for standard icons
  • keep important content inside the center safe area
  • use transparent backgrounds for icons
Good icons make the installed PWA look more like a real app.

End-to-End Flow

A PWA works by combining manifest, service worker, cache, and browser install behavior.

1. HTML links manifest and loads script.js
2. script.js registers sw.js
3. install phase caches important assets
4. fetch phase intercepts browser requests
5. cache hit serves file from local cache
6. cache miss fetches from network
7. network failure returns offline fallback
8. activate phase cleans old cache versions

Result:

  • faster loading
  • offline support
  • reduced network dependency

PWA Overview Table

PartPurpose
PWAWeb app with native app-like experience
HTTPSRequired for secure service worker usage
Service WorkerHandles cache, fetch, offline support, and updates
ManifestDefines app metadata and install behavior
Install PromptLets user add app to home screen or desktop
Cache FirstServes cached assets before network
Offline FallbackShows app shell when network fails
Activate EventRemoves old cache versions

Basic Checklist

Serve the app over HTTPS
Create manifest.json
Add name, short_name, start_url, display, colors, scope, and icons
Link manifest in index.html
Add theme-color meta tag
Create sw.js
Register sw.js from script.js
Cache important assets in install event
Use fetch event for cache-first behavior
Return offline fallback when network fails
Clean old cache versions in activate event
Use proper 192x192 and 512x512 icons
Test install prompt and offline behavior

Interview Style Answer

A Progressive Web App is a web application built with HTML, CSS, and JavaScript that provides an app-like experience through installability, offline support, fast loading, and responsive behavior. A PWA requires HTTPS and a web app manifest for installability in modern browsers, while a service worker is commonly used for offline support and cache control. The manifest defines app metadata like name, icons, theme color, start URL, display mode, and scope. The service worker acts as a proxy between the browser, cache, and network. It registers from script.js, caches important assets during the install event, intercepts requests during the fetch event using a cache-first strategy, returns an offline fallback when the network fails, and cleans old cache versions during activation.


One-Line Summary

PWA = An installable, offline-capable web app powered by HTTPS, Service Worker, and Web App Manifest.

Final Mental Model

Manifest -> makes app installable
Service Worker -> makes app offline-capable
Cache -> makes app fast after first load
HTTPS -> makes powerful browser features safe