Top 50 Progressive Web Apps Interview Questions (2026)

The 50 Progressive Web Apps questions interviewers actually ask, with direct answers, real service worker and manifest snippets, and what the interviewer is listening for. Grouped for freshers, intermediate, and experienced rounds.

50 questions with answers

What Is Progressive Web Apps?

Key Takeaways

  • A Progressive Web App is a website built with web tech that can install to the home screen, run offline, and use device features, all from a single codebase.
  • The two required building blocks are a service worker (a background script that intercepts network requests) and a web app manifest (JSON that describes the app so it can install).
  • Interviews test judgment as much as APIs: which caching strategy fits which asset, why HTTPS is mandatory, how updates roll out, and what a PWA still can't do that a native app can.
  • This page is a question bank: work your tier first, read one tier up, and say answers out loud, because delivery and reasoning get evaluated too.

A Progressive Web App (PWA) is a web app built with standard web technology, HTML, CSS, and JavaScript, that behaves more like an installed app. It can be added to the home screen, launched in its own window without browser chrome, work offline or on a flaky network, and reach device capabilities like push notifications and the camera, all from one codebase that also runs as a normal website. The official Chrome documentation on web.dev frames a PWA as capable, installable, and reliable, and those three words are a clean summary of what the term means. Two pieces make it real: a service worker, a background script that sits between the app and the network and can serve cached responses, and a web app manifest, a small JSON file that tells the browser the app's name, icons, and how to display it so it can be installed. In interviews, PWA questions probe how you reason about trade-offs: when to cache-first versus network-first, why a service worker only runs over HTTPS, how a new service worker takes over from an old one, and where a PWA still falls short of native. This page collects the 50 questions that come up most, each with a direct answer plus real snippets. Pair this bank with our AI interview preparation guides for the live-interview format, since the first frontend round is increasingly an AI-driven technical screen.

50Questions with answers on this page
3Difficulty tiers: freshers, intermediate, experienced
2Core building blocks: service worker and web app manifest
HTTPSRequired to register a service worker in production

Watch: Progressive Web Apps (PWAs): New features & APIs

Video: Progressive Web Apps (PWAs): New features & APIs (Chrome for Developers, YouTube)

Test yourself and earn a certificate

10 quick questions. Score 70%+ to download your Progressive Web Apps certificate.

Jump to quiz

All Questions on This Page

50 questions
PWA Interview Questions for Freshers
  1. 1. What is a Progressive Web App?
  2. 2. Why would a team choose a PWA over a regular website or a native app?
  3. 3. What is a service worker?
  4. 4. What is the web app manifest and what goes in it?
  5. 5. How do you register a service worker, and where does scope come from?
  6. 6. What are the main service worker lifecycle events?
  7. 7. How does caching work in a PWA, and which API do you use?
  8. 8. How does a PWA work offline?
  9. 9. Why do service workers require HTTPS?
  10. 10. How does a PWA get installed on a device?
  11. 11. What is the app shell model?
  12. 12. Is every single-page app a PWA?
  13. 13. What's the difference between a responsive website and a PWA?
  14. 14. How do you check whether a site qualifies as a PWA?
  15. 15. Why does the manifest need multiple icon sizes?
  16. 16. What is the fetch event in a service worker?
  17. 17. What do start_url and scope mean in a manifest?
PWA Intermediate Interview Questions
  1. 18. What are the main caching strategies and when do you use each?
  2. 19. Show how you'd implement a cache-first fetch handler.
  3. 20. How does a service worker update itself, and how do you avoid a bad update experience?
  4. 21. How do you handle cache versioning and cleanup?
  5. 22. How do push notifications work in a PWA?
  6. 23. What is Background Sync and what problem does it solve?
  7. 24. When do you use IndexedDB versus the Cache API in a PWA?
  8. 25. How would you implement network-first with a cache fallback?
  9. 26. A service worker isn't controlling some pages. What's the likely cause?
  10. 27. What is Workbox and why use it instead of hand-writing a service worker?
  11. 28. How do you show a custom offline page instead of the browser's error?
  12. 29. What are the manifest display modes and how do they differ?
  13. 30. How much can a PWA store, and what happens when it's full?
  14. 31. What PWA features behave differently across browsers, especially on iOS?
  15. 32. What do skipWaiting and clients.claim do, and when do you use them?
  16. 33. How do you support install on iOS given no beforeinstallprompt?
  17. 34. How do frameworks like Next.js or Angular help you build a PWA?
PWA Interview Questions for Experienced Engineers
  1. 35. What are the common performance pitfalls of a service worker?
  2. 36. What are the security considerations around service workers?
  3. 37. Users are stuck on an old version because of a cached service worker. How do you recover?
  4. 38. Where does a PWA still fall short of a native app?
  5. 39. Which performance metrics matter for a PWA, and how does a service worker affect them?
  6. 40. How do you decide what to precache versus cache at runtime?
  7. 41. How do you handle cache invalidation for a PWA's assets?
  8. 42. How do PWAs affect SEO and indexability?
  9. 43. How would you design a feature that works offline-first?
  10. 44. How do the page and service worker communicate?
  11. 45. How do you get a PWA into an app store, and what is a Trusted Web Activity?
  12. 46. Which newer web capabilities extend what a PWA can do?
  13. 47. How do you test a PWA, including its offline and update behavior?
  14. 48. When would you advise against building a PWA?
  15. 49. Is the app shell model still the right pattern with server-side rendering and streaming?
  16. 50. How do you monitor and debug a service worker in production?

PWA Interview Questions for Freshers

Freshers17 questions

The fundamentals every entry-level round checks: what a PWA is, service workers, the manifest, caching basics, and the offline idea underneath. If any answer here surprises you, that's your study list.

Q1. What is a Progressive Web App?

A Progressive Web App is a website built with normal web tech, HTML, CSS, and JavaScript, that can install to the home screen, run offline, and use device features like push notifications, all from one codebase. It's still a web app you reach by URL, but it behaves more like an installed app.

The three words people use are capable, installable, and reliable. Two pieces make that real: a service worker for offline and background work, and a web app manifest that describes the app so the browser can install it. Everything else is enhancement on top of a regular site.

Key point: Lead with 'a website that can install and work offline, from one codebase'. Interviewers open with this to hear whether you get the concept or just recite a feature list.

Watch a deeper explanation

Video: PWA Tutorial for Beginners #1 - What Are PWA's? (Net Ninja, YouTube)

Q2. Why would a team choose a PWA over a regular website or a native app?

Over a regular website, a PWA adds installability, offline support, and re-engagement through push, so users can keep it on their home screen and it survives a bad network. Over a native app, it keeps one codebase, ships updates instantly without an app store review, and is reachable by a plain link.

The honest framing is trade-offs. A PWA gives reach and update speed; a native app gives deeper platform integration and full device APIs, especially on iOS where web APIs lag. Teams pick a PWA when reach, one codebase, and fast iteration matter more than the last mile of native integration.

Key point: The it as a trade-off, not a winner. 'One codebase and instant updates versus deeper native integration' is the balanced answer this checks for.

Q3. What is a service worker?

A service worker is a JavaScript file the browser runs in the background, on its own thread, separate from the page. It sits between your app and the network as a programmable proxy: it can intercept requests, serve cached responses, and keep working even when the page is closed.

That's what makes offline, precaching, and push notifications possible. It has no DOM access and only runs over HTTPS (or localhost). You register it once from the page, and from then on it controls the pages in its scope.

javascript
// register a service worker from the page
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js')
    .then((reg) => console.log('registered', reg.scope))
    .catch((err) => console.error('failed', err));
}

Key point: Call it 'a background script that acts as a network proxy'. That one phrase covers offline, caching, and push in a single idea, which is exactly what the question wants.

Watch a deeper explanation

Video: PWA Tutorial for Beginners #6 - Intro to Service Workers (Net Ninja, YouTube)

Q4. What is the web app manifest and what goes in it?

The web app manifest is a small JSON file that describes the app to the browser so it can be installed. It lists the app name, icons in several sizes, the start URL, a theme color, and a display mode that controls whether it opens in its own window or a browser tab.

You link it from the HTML head, and the browser reads it to build the install prompt and the home-screen icon. Without a valid manifest (and a service worker), the browser won't offer to install the app.

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

Key point: List the load-bearing fields: name, icons, start_url, display. Knowing that install needs both a manifest and a service worker is the follow-up they'll push on.

Q5. How do you register a service worker, and where does scope come from?

You call navigator.serviceWorker.register with the path to the worker file, usually after checking the API exists. Registration is where the browser downloads the file and kicks off the install lifecycle.

Scope is the set of pages a worker controls, and it defaults to the folder the worker file lives in. A worker at /sw.js controls the whole origin; one at /app/sw.js controls only /app/. That's why the file usually sits at the root: to control the entire site.

javascript
// scope defaults to the worker's directory
navigator.serviceWorker.register('/sw.js', { scope: '/' });
// a worker at /app/sw.js can only control pages under /app/

Key point: Mention that a root-level worker controls the whole origin because scope follows the file's directory. That detail shows you've placed a worker deliberately, not by copy-paste.

Q6. What are the main service worker lifecycle events?

The three you name most are install, activate, and fetch. install fires once when a new worker is downloaded, and it's where you open a cache and precache the app shell. activate fires after install and is where you delete stale caches from older versions. fetch fires on every network request in scope, where you decide to serve from cache or network.

Between install and activate there's a waiting stage: a new worker holds back until the old one's pages close, so two versions don't run at once. You skip that wait with skipWaiting when you want the update to take over right away.

The service worker lifecycle

1Register
the page calls register(); the browser downloads the worker file
2Install
install event fires once; precache the app shell here
3Activate
activate event fires; clean up old caches from previous versions
4Control (fetch)
the worker intercepts fetch events for pages in its scope

A new worker waits until old clients close before it activates, unless you call skipWaiting() to take over immediately.

Key point: Map each event to its job: install precaches, activate cleans up old caches, fetch intercepts. Reciting the names without the jobs reads shallow.

Watch a deeper explanation

Video: Progressive Web Apps (PWAs): New features & APIs (Chrome for Developers, YouTube)

Q7. How does caching work in a PWA, and which API do you use?

You cache in the service worker using the Cache API (Cache Storage), which stores Request and Response pairs. On install you open a named cache and add your core files; on fetch you check that cache and either return the hit or go to the network.

It's different from the browser's built-in HTTP cache because you control it in code: you decide what to store, when to update it, and what to serve offline. localStorage doesn't work here, it's synchronous and unavailable to workers, so the Cache API is the right tool.

javascript
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open('shell-v1').then((cache) =>
      cache.addAll(['/', '/index.html', '/styles.css', '/app.js'])
    )
  );
});

Key point: Say 'Cache API, not localStorage'. Knowing localStorage is synchronous and unavailable to workers is the precise reason the key point is.

Q8. How does a PWA work offline?

The service worker makes it possible. On install it precaches the app shell (the HTML, CSS, and JS needed to render the UI), so on a repeat visit those files come from the cache instead of the network. When the fetch event fires and there's no connection, the worker returns the cached response.

For content that isn't cached, you serve a fallback: a cached offline page, or a cached last-known version of the data. Offline isn't automatic, you design which requests are cache-first, which fall back, and what the user sees when something genuinely isn't available.

Key point: Stress that offline is designed, not free. Naming the app shell precache plus an offline fallback shows you understand there's a deliberate strategy behind it.

Q9. Why do service workers require HTTPS?

Because a service worker can intercept and rewrite every request the page makes, it's a lot of control to hand to code. Requiring a secure context (HTTPS) stops an attacker on the network from injecting a malicious worker that could hijack the whole site.

The one exception is localhost, which counts as a secure context so you can develop without a certificate. In production, no HTTPS means no service worker, and therefore no offline, no precaching, and no push.

Key point: the rule maps to the worker's power over requests. 'It can intercept everything, so it must be a secure context' is the reasoning, not just 'HTTPS is required'.

Q10. How does a PWA get installed on a device?

The browser decides a site is installable when it has a valid manifest with the right fields and a registered service worker, served over HTTPS. On desktop and Android Chrome, it fires a beforeinstallprompt event you can capture to show your own install button, then call prompt() when the user clicks it.

iOS is different: Safari doesn't fire that event, so users install through the share sheet's Add to Home Screen. That platform gap is worth naming, because 'installable everywhere' isn't quite true.

javascript
let deferred;
window.addEventListener('beforeinstallprompt', (e) => {
  e.preventDefault();
  deferred = e;            // stash it, show your own button
});
// later, on button click:
// deferred.prompt();

Key point: Mention that iOS installs via the share sheet, not beforeinstallprompt. Knowing that platform difference separates people who've shipped a PWA from those who've only read the happy path.

Q11. What is the app shell model?

The app shell is the minimal HTML, CSS, and JavaScript needed to render the interface: the layout, navigation, and styling, without the dynamic content. You cache the shell on install so it paints instantly on repeat visits and offline.

The content (the changing data) loads into the shell separately, usually from the network with its own caching. Splitting the two is what makes a PWA feel fast: the frame appears immediately from cache while the data streams in.

Key point: Frame it as 'cache the frame, load the content into it'. That separation is the whole point, and the key point is you make it.

Q12. Is every single-page app a PWA?

No. A single-page app (SPA) is an architecture: one page that swaps content with JavaScript instead of full reloads. A PWA is a set of capabilities: installable, offline-capable, service-worker-backed. They're often combined, but they're not the same thing.

You can have an SPA that's not a PWA (no service worker, no manifest, breaks offline), and a PWA that's a multi-page app. The PWA label is about the service worker, manifest, and HTTPS, not about how many pages the app has.

Key point: Draw the line clearly: SPA is architecture, PWA is capabilities. Conflating them is a common junior mistake this question hunts for.

Q13. What's the difference between a responsive website and a PWA?

Responsive means the layout adapts to screen size using flexible CSS, media queries, and fluid grids. It's about how the site looks across devices. A PWA is about capabilities: install, offline, background sync, push.

A good PWA is usually responsive too, because it should feel right on the phone it's installed on. But responsiveness alone doesn't make a PWA, and being a PWA doesn't guarantee good responsive design. They solve different problems.

Key point: Keep the two axes separate: responsive is layout, PWA is capability. Answering that they're unrelated concerns that often ship together is the mature take.

Q14. How do you check whether a site qualifies as a PWA?

Run a Lighthouse audit in Chrome DevTools. It checks the installability signals: a valid manifest with the required fields, a registered service worker, HTTPS, and whether the app responds when offline. It flags exactly what's missing.

The Application panel in DevTools is the other tool: it shows your registered service workers, the manifest the browser parsed, and the contents of your caches, so you can confirm what's actually stored and served.

Key point: Naming both Lighthouse and the DevTools Application panel shows you've actually debugged a PWA, not just built one that happened to work.

Q15. Why does the manifest need multiple icon sizes?

Different surfaces need different icon sizes: the home screen, the splash screen, the task switcher, and the install prompt each pick the size that fits. Providing several sizes (192 and 512 are the common baseline) lets the browser choose the right one instead of scaling a single image badly.

512x512 also feeds the splash screen the browser generates on launch. A maskable icon variant lets the platform crop it into whatever shape (circle, squircle) the OS uses, so it doesn't get an awkward border.

Key point: Mention maskable icons for adaptive shapes. It's a small detail that signals you've actually gone through the install experience on a real device.

Q16. What is the fetch event in a service worker?

The fetch event fires whenever a page in the worker's scope makes a network request: a page load, an image, an API call, anything. Inside the handler you call event.respondWith and return a Response, from the cache, from the network, or one you build yourself.

That's the hook that makes offline and caching work, because you get to decide how every request is answered. If you don't call respondWith, the request just goes to the network normally, so the worker only changes behavior for the requests you choose to handle.

javascript
self.addEventListener('fetch', (event) => {
  // if you don't call respondWith, the browser handles it normally
  event.respondWith(caches.match(event.request).then((hit) => hit || fetch(event.request)));
});

Key point: Say that skipping respondWith lets the request go to the network untouched. Knowing the worker only intercepts what you handle is a detail beginners miss.

Q17. What do start_url and scope mean in a manifest?

start_url is the URL the app opens to when it's launched from the home screen. It's often the root or a dedicated landing route, and you can add tracking params to tell installed launches apart from browser visits. If it's wrong, the installed app opens to the wrong place.

scope defines which URLs are considered part of the app. handle outside the scope and the browser shows a mini in-app browser bar to signal you've left the app. Setting scope to the root keeps the whole site inside the installed experience.

Key point: Distinguish start_url (where it launches) from scope (what counts as in-app). Mixing them up is common, and the in-app browser bar on out-of-scope links is a nice detail to add.

Back to question list

PWA Intermediate Interview Questions

Intermediate17 questions

For candidates with working experience: caching strategies, the update lifecycle, background features, and the judgment questions that separate people who've shipped a service worker from those who've read about one.

Q18. What are the main caching strategies and when do you use each?

The common strategies are cache-first (check cache, fall back to network), network-first (try network, fall back to cache), stale-while-revalidate (serve cache now, update it in the background), cache-only, and network-only. Each trades freshness against speed and offline resilience differently.

Match the strategy to the asset. Static, versioned files (hashed JS, CSS, images) suit cache-first because they never change under the same URL. API data that must be current suits network-first. UI assets that can be slightly stale suit stale-while-revalidate for instant loads with eventual freshness.

StrategyBehaviorBest for
Cache-firstCache, then network on missStatic, versioned assets
Network-firstNetwork, then cache on failureFresh API data, HTML
Stale-while-revalidateCache now, refresh in backgroundAssets that tolerate slight staleness
Network-onlyAlways network, no cacheNon-cacheable requests, analytics

Key point: Don't just define the strategies, match each to an asset type. 'Cache-first for hashed assets, network-first for API data' is the answer that proves you've made these calls.

Watch a deeper explanation

Video: Progressive Web Apps in 100 Seconds // Build a PWA from Scratch (Fireship, YouTube)

Q19. Show how you'd implement a cache-first fetch handler.

In the fetch event you check the cache with caches.match. If there's a hit, return it. If not, fetch from the network, and optionally put a copy into the cache before returning it so the next request is a hit.

You clone the response before caching, because a Response body is a stream that can only be read once: one copy goes to the cache, one goes back to the page. Forgetting the clone is a classic bug where the page gets an empty body.

javascript
self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then((hit) => {
      if (hit) return hit;
      return fetch(event.request).then((res) => {
        const copy = res.clone();          // stream reads once
        caches.open('runtime').then((c) => c.put(event.request, copy));
        return res;
      });
    })
  );
});

Key point: Volunteer the response.clone() detail and why. Knowing a Response body is a one-read stream is exactly the gotcha this question is testing.

Q20. How does a service worker update itself, and how do you avoid a bad update experience?

The browser re-checks the worker file on navigation (and periodically). If the bytes differ at all, it treats it as a new version and runs install for the new worker. That new worker enters the waiting state and only takes control once every tab controlled by the old worker has closed.

The trap is forcing skipWaiting blindly, which can swap the worker mid-session and mismatch cached assets against a running page. The good pattern is to install quietly, detect the waiting worker, and prompt the user to reload to get the update, so the switch happens at a safe moment they chose.

How a service worker update rolls out

1Byte-diff
browser re-downloads sw.js and installs it if even one byte changed
2Install (new)
the new worker precaches its assets in the install event
3Waiting
it waits while old-version tabs stay open, unless skipWaiting() is called
4Activate + claim
on activation it cleans old caches; clients.claim() takes control of open pages

The safe pattern: install silently, then prompt the user to reload so a fresh version doesn't swap under them mid-session.

Key point: Explain the waiting-then-prompt pattern rather than just calling skipWaiting. Understanding why an in practice swap is risky is the production signal here.

Q21. How do you handle cache versioning and cleanup?

The each cache with a version (shell-v2, runtime-v2). When you ship a new worker, its install precaches into the new-named cache, and its activate event deletes any cache whose name isn't in your current allowlist. That's how old assets get purged instead of accumulating forever.

Doing cleanup in activate matters because that's the point where the new worker is taking over and it's safe to remove what the old one relied on. Skip it and users carry stale caches and bloated storage across versions.

javascript
const CURRENT = ['shell-v2', 'runtime-v2'];
self.addEventListener('activate', (event) => {
  event.waitUntil(
    caches.keys().then((keys) =>
      Promise.all(keys.filter((k) => !CURRENT.includes(k)).map((k) => caches.delete(k)))
    )
  );
});

Key point: Say that cleanup belongs in the activate event and why. Deleting old caches at the wrong time (during install) can pull assets the old worker still needs.

Q22. How do push notifications work in a PWA?

Two APIs combine. The Push API lets your server send a message to the browser's push service even when the app is closed; the Notifications API displays it. You ask permission, subscribe the user via PushManager to get an endpoint, and send that subscription to your server.

When your server pushes, the service worker wakes on a push event and calls showNotification. The user doesn't need the tab open, that's the whole point. Permission is a real friction point, so you ask for it in context, not on first load, or users just deny it.

javascript
self.addEventListener('push', (event) => {
  const data = event.data ? event.data.json() : {};
  event.waitUntil(
    self.registration.showNotification(data.title || 'Update', {
      body: data.body,
      icon: '/icon-192.png',
    })
  );
});

Key point: Split it clearly: Push API delivers, Notifications API displays, and the service worker handles the push event. permission timing matters.

Q23. What is Background Sync and what problem does it solve?

Background Sync lets a PWA defer an action until the device has a stable connection. The classic case is a user submitting something offline: you register a sync tag, and the browser fires a sync event in the service worker once connectivity returns, where you retry the request.

It solves the lost-action problem: without it, an offline submit either fails or you hand-roll retry logic in the page, which dies when the tab closes. Support is uneven across browsers, so you treat it as an enhancement with a fallback, not a guarantee.

Key point: The offline-submit use case and that browser support is uneven. Presenting it as progressive enhancement, not a promise, is the honest, senior framing.

Q24. When do you use IndexedDB versus the Cache API in a PWA?

They store different things. The Cache API stores Request and Response pairs, it's for caching network assets and API responses to serve offline. IndexedDB is a structured, queryable database in the browser for application data: records you create, read, update, and query offline.

So you cache the app shell and asset responses with the Cache API, and store user-created data (a draft, a list, queued actions) in IndexedDB. Reaching for localStorage instead is the mistake: it's synchronous, size-limited, string-only, and unavailable in the service worker.

NeedCache APIIndexedDB
Store network responsesYesNot its job
Store structured app dataNoYes, with indexes and queries
Available in service workerYesYes
Good for offline drafts/queuesNoYes

Key point: Draw the line: Cache API for responses, IndexedDB for structured data. Adding 'not localStorage, it's sync and worker-unavailable' is the detail that lands.

Q25. How would you implement network-first with a cache fallback?

In the fetch handler you try the network first. On success you optionally update the cache and return the response. On failure (offline or an error), you fall back to caches.match to serve the last cached copy.

This suits HTML and API data where fresh matters but offline should still show something. You often add a timeout so a slow network doesn't hang the user forever before falling back to cache.

javascript
self.addEventListener('fetch', (event) => {
  event.respondWith(
    fetch(event.request)
      .then((res) => {
        const copy = res.clone();
        caches.open('runtime').then((c) => c.put(event.request, copy));
        return res;
      })
      .catch(() => caches.match(event.request))
  );
});

Key point: Mention adding a network timeout before falling back. Without it, a slow connection is worse than being offline, and interviewers like to probe that edge.

Q26. A service worker isn't controlling some pages. What's the likely cause?

Almost always scope. A worker only controls pages at or below its own directory, so /app/sw.js can't control the site root. Move the file to the root, or set the Service-Worker-Allowed header to widen the scope beyond the file's location.

The other common cause is the first load: a page that loaded before the worker registered isn't controlled until it reloads (or you call clients.claim() in activate to take over open pages immediately). So a fresh registration seems to do nothing until the next navigation.

Key point: Split the answer into scope and first-load control. Knowing clients.claim() takes over already-open pages is the detail that shows real debugging experience.

Q27. What is Workbox and why use it instead of hand-writing a service worker?

Workbox is a set of libraries from the Chrome team that wrap the common service worker patterns: routing, the standard caching strategies, precaching with revision hashes, expiration, and cleanup. You declare routes and strategies instead of hand-writing fetch handlers and cache versioning.

The value is that hand-rolled service workers are easy to get subtly wrong: cache versioning, response cloning, expiration, precache manifests. Workbox handles those correctly and integrates with build tools to generate a precache list automatically. For anything beyond a demo, most teams reach for it.

Key point: Frame it as 'the hard parts done correctly': versioning, expiration, precache manifests. Being able to hand-write a worker but choosing Workbox for production is the balanced answer.

Q28. How do you show a custom offline page instead of the browser's error?

Precache an offline.html during install. Then in the fetch handler, when a navigation request fails (the user is offline and the page isn't cached), return the cached offline page instead of letting the browser show its default error.

You scope this to navigation requests (event.request.mode === 'handle') so you don't return the offline HTML for a failed image or script. It's a small touch that makes offline feel intentional rather than broken.

javascript
self.addEventListener('fetch', (event) => {
  if (event.request.mode === 'navigate') {
    event.respondWith(
      fetch(event.request).catch(() => caches.match('/offline.html'))
    );
  }
});

Key point: Scope the fallback to navigation requests. Returning the offline HTML for a failed image is a bug interviewers like to catch.

Q29. What are the manifest display modes and how do they differ?

display controls how the installed app launches. fullscreen uses the entire screen with no system UI (games, media). standalone gives its own window without browser chrome but keeps the system status bar, and it's the most common for app-like PWAs. minimal-ui keeps a minimal set of navigation controls. browser opens it as a normal tab, effectively not app-like.

The browser falls back down the list if a mode isn't supported. Most product PWAs pick standalone: it feels native without hiding the OS status bar that fullscreen removes.

displayBrowser UITypical use
fullscreenNone at allGames, immersive media
standaloneNo browser chrome, keeps status barMost app-like PWAs
minimal-uiMinimal navigation controlsContent apps wanting back/reload
browserFull browser tabEffectively a normal site

Key point: Know that standalone is the common default and why (native feel without hiding the status bar). Reciting all four without a recommendation reads like memorization.

Q30. How much can a PWA store, and what happens when it's full?

Storage isn't unlimited. Browsers give an origin a quota based on available disk (often a percentage of free space), shared across the Cache API, IndexedDB, and other storage. You can check it with navigator.storage.estimate to see usage and quota.

When space runs low, the browser can evict your origin's storage, and by default it evicts best-effort data without warning. If your PWA truly needs its offline data to survive, you request persistent storage with navigator.storage.persist, which asks the browser not to evict it.

javascript
const { usage, quota } = await navigator.storage.estimate();
// ask the browser to keep this data across pressure
const persisted = await navigator.storage.persist();

Key point: Mention persistent storage and eviction. Assuming the cache lives forever is the mistake, and knowing storage.persist() exists is the detail that stands out.

Q31. What PWA features behave differently across browsers, especially on iOS?

iOS Safari is the big one. It supports service workers and offline, but historically lagged on Web Push (added later than others), doesn't fire beforeinstallprompt, installs only via the share sheet, and limits background features. So install UX and push need iOS-specific handling.

More broadly, Background Sync and some device APIs are Chromium-mostly. The right approach is feature detection and progressive enhancement: check whether an API exists, use it when it does, and give a working fallback when it doesn't, rather than assuming one browser's behavior everywhere.

Key point: Lead with iOS specifics (share-sheet install, later push support) and 'feature-detect, don't assume'. That's the practical cross-browser literacy this question checks.

Q32. What do skipWaiting and clients.claim do, and when do you use them?

skipWaiting tells a newly installed worker to activate immediately instead of waiting for old tabs to close. clients.claim, called in activate, makes the active worker take control of already-open pages that weren't controlled before, including the page that just registered it.

Together they force a fast takeover. The risk is doing it silently mid-session: the new worker's caches may not match the page the user is looking at, which can break assets. The safe pattern is to install quietly, then prompt the user to reload, calling skipWaiting only when they accept.

javascript
self.addEventListener('activate', (event) => {
  event.waitUntil(self.clients.claim());   // control open pages now
});
// skipWaiting() is usually triggered after a user reload prompt

Key point: Explain the pair together and the mid-session risk. Calling skipWaiting reflexively without a reload prompt is exactly the mistake this question probes.

Q33. How do you support install on iOS given no beforeinstallprompt?

iOS Safari doesn't fire beforeinstallprompt, so you can't show a one-tap install button the way you can on Chrome. Instead users install through the share sheet's Add to Home Screen, so the practical answer is to detect iOS Safari and show a short instruction (tap Share, then Add to Home Screen).

You also add the iOS-specific bits: an apple-touch-icon for the home-screen icon and apple-mobile-web-app-capable so it launches without Safari chrome. It's more manual than Android, and pretending install works identically everywhere is the trap.

Key point: Show you know the iOS path is manual (share sheet plus apple-touch-icon meta). Claiming install is one-tap everywhere is a red flag for anyone who's shipped to iOS.

Q34. How do frameworks like Next.js or Angular help you build a PWA?

They automate the boilerplate. Angular has a first-party service worker package that generates a precache manifest and handles versioned updates. Next.js and other React setups use plugins (often Workbox under the hood) to generate the service worker and inject the precache list at build time, so hashed assets get cached and invalidated correctly.

The value is that build integration produces the precache manifest for you, keeping it in sync with your actual output, which is tedious and error-prone by hand. You still own the strategy decisions (what's cache-first, what's network-first) and the update UX; the framework just removes the mechanical work.

Key point: Credit the framework for the precache manifest and update wiring, but stress you still own the caching strategy. That split shows you understand what's automated versus what's judgment.

Back to question list

PWA Interview Questions for Experienced Engineers

Experienced16 questions

advanced rounds probe architecture, performance, security, and production scars. Expect every answer here to draw a follow-up about trade-offs and failure modes.

Q35. What are the common performance pitfalls of a service worker?

The biggest one is precaching too much on install: pull in a giant asset list and the first visit is slower and the worker is slow to activate. Precache only the app shell and let runtime caching fill the rest on demand. Another is a fetch handler that adds latency by always awaiting the network before the cache, or by caching things that shouldn't be cached.

Also watch the double-request trap: an over-eager service worker can turn one navigation into a cache lookup plus a network fetch plus a cache write on the hot path. Keep the fetch handler lean, scope which requests it even intercepts, and measure with real navigations rather than assuming the worker is always a win.

Key point: The over-precaching and a heavy fetch handler as the real costs. Acknowledging a service worker can add latency, not just remove it, is the production signal.

Q36. What are the security considerations around service workers?

A service worker can intercept and rewrite every request in scope, so a compromised one is a serious problem: it could serve altered responses to every visitor until the worker updates. HTTPS is the baseline defense, and you keep the worker file itself under tight review because it's high-privilege code.

Beyond that: be careful what you cache (never cache responses with sensitive per-user data in a shared cache), respect cache headers and auth, and remember the worker persists, so a bad deploy can pin a broken or malicious version until it's replaced. Treat the service worker like production infrastructure, because it effectively is.

Key point: Frame the worker as high-privilege code that persists across visits. 'A bad worker sticks around until replaced' is the risk the question needs you to articulate.

Q37. Users are stuck on an old version because of a cached service worker. How do you recover?

First, understand why: the worker or its cached HTML is being served without revalidation, so the browser never sees the new worker. The fix pattern is to make sure sw.js is served with no-cache (short or zero HTTP cache lifetime) so the browser always re-checks it, then ship a new worker that cleans old caches in activate and prompts a reload.

For users already stuck, the new worker needs to detect the stale caches by version and purge them on activate, and you may use clients.claim() plus a reload prompt to force the transition. The deeper lesson is never let the service worker file itself be cached hard, that's how sites get pinned to a broken version.

Key point: Root-cause it as a hard-cached sw.js, then fix with no-cache headers plus versioned cleanup. This is a real production scar, and interviewers ask it to hear if you've been burned.

Q38. Where does a PWA still fall short of a native app?

Deep platform integration. Native apps get full access to hardware and OS features (some Bluetooth and NFC modes, tight background execution, certain sensors, richer notifications) that the web either lacks or gates behind permissions. iOS in particular limits web APIs and background work more than Android.

There's also discoverability and trust: many users still expect to find apps in a store, and some device features (contacts, certain filesystem access, background location) are limited or unavailable. The honest answer is a PWA covers most needs with far less cost, and you reach for native when a specific hard requirement (heavy background processing, a native-only API) genuinely needs it.

Key point: Give concrete gaps (background execution, some device APIs, iOS limits) rather than a vague 'less capable'. Specifics prove you've actually hit the wall.

Q39. Which performance metrics matter for a PWA, and how does a service worker affect them?

The Core Web Vitals apply: Largest Contentful Paint for loading, Interaction to Next Paint for responsiveness, and Cumulative Layout Shift for visual stability. A cached app shell helps LCP on repeat visits by painting instantly, but the service worker can't fix a slow first visit, that's still your critical-path work.

The nuance is that INP measures main-thread responsiveness, and a service worker runs off the main thread, so it doesn't directly help INP; heavy JavaScript in the page still does. So you use the worker to make repeat loads fast and offline-resilient, and separately keep the main thread light for interaction responsiveness.

Key point: Reference INP (not FID) for responsiveness and note the worker is off-main-thread. Knowing what the service worker does and doesn't help is the precise, current answer.

Q40. How do you decide what to precache versus cache at runtime?

Precache the small, stable, always-needed set: the app shell, core CSS and JS, the offline fallback, key icons. It's the stuff the app can't render without, so paying for it once on install is worth it. Keep the precache list tight and revisioned so updates purge cleanly.

Cache at runtime the large or unpredictable set: images, API responses, less-visited routes. You don't know in advance which the user needs, and precaching all of it bloats install and storage. Runtime caching with the right strategy (and expiration limits so it doesn't grow forever) covers those on demand.

Key point: The rule is 'precache the critical shell, runtime-cache the long tail'. Adding expiration limits on runtime caches shows you've thought about storage growth in production.

Q41. How do you handle cache invalidation for a PWA's assets?

The clean approach is content hashing plus precache revisions. Build tools fingerprint asset filenames (app.a1b2c3.js), so a changed file gets a new URL and the old cached one is simply never requested again. Your precache manifest lists each file with a revision, and a new service worker precaches the changed ones and drops the stale entries.

For runtime-cached responses (APIs, images) you use expiration: a max age or max entry count so entries age out, plus network-first or stale-while-revalidate where freshness matters. The failure mode to avoid is caching un-hashed HTML or JS cache-first, that's how users get pinned to old code with no way to update.

Key point: Lead with content hashing so URLs change on edit. Warning against cache-first on un-hashed HTML is the gotcha that shows you've debugged a stale-asset incident.

Q42. How do PWAs affect SEO and indexability?

The risk is client-rendered content: if the meaningful HTML only appears after JavaScript runs, crawlers that don't execute JS well may index an empty shell. The service worker doesn't change that, crawlers don't run your service worker. So the fix is server-side rendering or prerendering the important content, not relying on the client.

Otherwise a PWA is a website and indexes like one: real URLs per view, proper links, correct titles and metadata, and no content locked behind interaction. Treat the app shell as an enhancement over server-rendered HTML, and SEO stays intact.

Key point: Separate the concerns: SEO is about server-rendered content and real URLs, the service worker is irrelevant to crawlers. Recommending SSR/prerender for the shell-only risk is the answer.

Q43. How would you design a feature that works offline-first?

Start from the data. Decide what lives locally in IndexedDB so the UI can read and write with no network, and have the app treat local state as the source of truth for the session. Writes go to local storage immediately and queue an outbound change, so the user never waits on the network to act.

Then sync: flush the queue when connectivity returns (Background Sync where supported, a manual retry loop where not), and handle conflicts explicitly, last-write-wins, per-field merge, or server-authoritative, because the same record can change in two places while offline. Naming conflict resolution as a first-class problem is what separates a real offline design from 'just cache the API'.

Designing an offline-first PWA feature

1Model the data
decide what's stored locally in IndexedDB and what stays server-only
2Write locally first
the UI reads and writes local state so it works with no network
3Queue and sync
outbound changes queue, then flush via Background Sync when online
4Reconcile conflicts
define who wins when local and server data diverge on reconnect

Offline-first isn't caching bolted on late. Conflict resolution is the hard part, and skipping it is where offline features quietly corrupt data.

Key point: Anchor the whole answer in conflict resolution and local-first writes. Candidates who only talk about caching responses miss that offline writes are the actual hard part.

Q44. How do the page and service worker communicate?

Through messaging, because the worker has no DOM access. The page posts to the worker via the active registration, and the worker posts back to clients it looks up with clients.matchAll or the message event's source. Each side listens for 'message' events and reacts.

You use this for things like telling the page a new version is waiting (so it can show a reload prompt), or the page asking the worker to cache something on demand. For more structured request/response, a MessageChannel gives you a dedicated port per exchange instead of one shared channel.

javascript
// page -> worker
navigator.serviceWorker.controller.postMessage({ type: 'SKIP_WAITING' });

// worker -> pages
self.addEventListener('message', (e) => {
  if (e.data.type === 'SKIP_WAITING') self.skipWaiting();
});

Key point: Note the worker has no DOM, so postMessage is the only bridge. MessageChannel for structured request/response matters.

Q45. How do you get a PWA into an app store, and what is a Trusted Web Activity?

On Android, a Trusted Web Activity (TWA) wraps your PWA in a thin native shell that runs it full-screen in Chrome without browser UI, and you publish that wrapper to the Play Store. Tools like Bubblewrap generate the wrapper. Ownership is verified via Digital Asset Links so the URL bar can be hidden.

It's the same PWA, same URL, same service worker, just distributed through the store for users who look there. On iOS the story is weaker: you typically wrap the PWA in a WebView-based container to submit it, with the platform's usual constraints. The point is the web app stays the source of truth; the store listing is a distribution channel.

Key point: Know TWA plus Bubblewrap and Digital Asset Links for Android, and that iOS is more constrained. This is a real 'have you shipped to a store' filter.

Q46. Which newer web capabilities extend what a PWA can do?

The capability set has grown: the File System Access API for reading and writing local files, the Web Share API to hook into the native share sheet, the Badging API for an app-icon count, Periodic Background Sync for scheduled refreshes, and Web Push for notifications. These close part of the gap with native.

The catch is uneven support, especially on iOS, and permission friction. So you feature-detect each one and enhance progressively: use the File System Access API where present, fall back to a download link where not. Treating them as bonuses over a working baseline, not requirements, is how you ship them safely.

Key point: The a few real APIs (File System Access, Web Share, Badging) and immediately pair them with feature detection. Listing APIs without the support caveat indicates naive.

Q47. How do you test a PWA, including its offline and update behavior?

Layer it. Unit-test the caching logic and message handlers in isolation. Use DevTools to simulate offline and throttled networks, and the Application panel to inspect registered workers, caches, and the parsed manifest. Lighthouse (in CI too) guards the installability and performance baseline on every build.

The parts people forget are update and offline paths: test that a new worker version cleans old caches and prompts a reload, and that offline shows your fallback rather than a broken page. Automated end-to-end tools that drive a real browser (with service workers enabled) catch the lifecycle bugs unit tests can't.

Key point: Call out testing the update and offline paths specifically, plus Lighthouse in CI. Most candidates test the happy online path and miss the lifecycle, which is where PWA bugs live.

Q48. When would you advise against building a PWA?

When the core requirement is something the web can't do well: heavy sustained background processing, deep OS integration, or platform APIs that are native-only. If the product lives or dies on those, a PWA fights the platform and a native or hybrid app is the honest call.

Also when the audience is entirely iOS and depends on features iOS gates or omits, or when a store presence and native trust signals are non-negotiable for the business. A PWA shines for broad reach, one codebase, and fast iteration; when those aren't the priorities and a hard native requirement is, recommending against it is the mature answer.

Key point: Being willing to say 'don't build a PWA here' with a concrete reason is a strong production signal. Interviewers ask this to check you're not treating PWA as a hammer for every nail.

Q49. Is the app shell model still the right pattern with server-side rendering and streaming?

It's shifted. The classic app shell (cache an empty frame, fill it client-side) was built for client-rendered SPAs. With modern server-side rendering and streaming, the server sends meaningful HTML on the first request, so caching a blank shell can actually hurt: you'd serve an empty frame when the server could have streamed real content.

The current thinking is to cache full rendered responses with the right strategy (network-first for HTML, stale-while-revalidate where staleness is fine) and precache only the truly static assets. So the service worker still matters for offline and repeat-visit speed, but blindly precaching a client-rendered shell is dated advice when your framework streams HTML.

Key point: Show you know the app shell was an SPA-era pattern and streaming SSR changes the calculus. Reciting 'always cache the app shell' without that nuance indicates out of date.

Q50. How do you monitor and debug a service worker in production?

You can't rely on local DevTools for real users, so you instrument. Report service worker lifecycle events and errors to your logging or error-tracking tool, tag requests so you can see cache-hit versus network rates, and track how many users are on the current worker version versus stuck on an old one.

The events worth watching: install and activation failures, unhandled errors inside fetch handlers (which can break the whole site for that user), and slow cache operations. Because a bad worker persists across visits, you also want a fast kill switch: a way to ship a minimal worker that unregisters or clears caches, so one bad deploy doesn't pin users to a broken version.

Key point: The kill-switch idea (ship a worker that can unregister or clear caches). Planning for a bad worker in production, not just building the happy path, is the senior instinct here.

Back to question list

PWA vs Native App vs Regular Website

A PWA sits between a plain website and a native app. Against a regular website, it adds installability, offline behavior, and background features. Against a native app, it trades some deep platform integration for one codebase, instant updates without an app store review, and reach through a URL. Knowing where each option fits, and saying the trade-off out loud, is itself an interview signal.

AspectRegular websitePWANative app
InstallNo install, just a URLInstalls from the browser, no store neededInstalls from an app store
OfflineFails without networkWorks offline via service worker cacheWorks offline by design
DistributionAny browser via a linkAny browser link, plus optional store listingStore review and approval
UpdatesInstant on reloadInstant, controlled by the service workerUser updates through the store
Device accessLimited web APIsGrowing web APIs, still gaps on iOSFull platform APIs

How to Prepare for a Progressive Web Apps Interview

Prepare in layers, and trade-offs out loud is the explanation path. Most PWA rounds move from concept questions to a hands-on task (register a service worker, write a manifest, add caching) to a scenario discussion, so rehearse each stage rather than only reading answers.

  • Master your tier's concepts until you can explain them without notes, then read one tier up for the stretch questions.
  • Build a tiny PWA: a manifest, a registered service worker, and one caching strategy, then audit it in Chrome DevTools Lighthouse.
  • Rehearse scenario answers with a structure: clarify, propose a strategy, The trade-off, describe how you'd test and update it.
  • Take the quiz on this page to find weak spots, then revisit those questions before the real round.

The typical PWA interview flow

1Recruiter or phone screen
background, projects you've shipped, a few concept checks
2Technical concepts
service workers, manifest, caching strategies, offline, HTTPS
3Hands-on or whiteboard
write a manifest or service worker, add a cache, debug a stale asset
4Scenario and design
offline UX, update strategy, push notifications, native trade-offs

Earlier rounds increasingly run as AI-driven technical interviews. The concepts on this page are what gets probed at every stage.

Test Yourself: Progressive Web Apps Quiz

Ready to test your Progressive Web Apps knowledge?

10 questions, about 6 minutes. Score 70% or higher to earn a shareable certificate.

10 questions Instant feedback Free certificate on 70%+

Frequently  Asked  Questions

Which Progressive Web Apps topics should I prioritize before a technical round?

Prioritize the areas that change real decisions: fundamentals, practical tasks, debugging, trade-offs, and evidence. The highest-value questions are tied to a project example, a validation check, or a failure mode.

Do I need to build a full PWA to pass the interview?

You don't need a production app, but you do need to have written a manifest and registered a service worker at least once. A tiny demo with one caching strategy, audited in Lighthouse, teaches you more than any amount of reading. Interviewers can tell within a couple of questions whether you've actually shipped a service worker or only read about one.

Which browsers and tools do these answers assume?

The concepts are standards-based and work across modern browsers. Examples use the plain Service Worker and Cache APIs plus a web app manifest, with Chrome DevTools and Lighthouse for auditing. Where iOS or Safari behaves differently, the answers say so, because those gaps are a favorite interview topic.

How long does it take to prepare for a PWA interview?

If you already build for the web, one week of an hour a day covers this bank with a small demo app. Starting colder, plan two to three weeks and build daily: register a service worker, write a manifest, add cache-first and network-first strategies, and test offline. Reading answers without running anything is how preparation quietly fails here.

Do interviewers ask exactly these questions?

The concepts repeat far more reliably than the exact wording. Interviewers rephrase, chain follow-ups, and push toward whatever you claim confidence in. Prepare the underlying ideas, service workers, the manifest, caching strategies, offline UX, and updates, and the phrasing takes care of itself.

Is there a way to test my PWA knowledge?

Yes. The quiz on this page scores you as you go and explains every answer, so you find your weak spots fast. Pass the threshold and you can download a shareable certificate with your name and score, free and with no sign-up. It's the quickest way to check yourself before the real round.

From the team that builds coding interviews

Hyring builds the AI Coding Interviewer that runs live technical rounds in 20+ languages for 5,000+ hiring teams. These Progressive Web Apps questions and scoring notes reflect what actually gets asked and evaluated inside the interviews we host.

See how the AI Coding Interviewer works

Sources

Adithyan RKWritten by Adithyan RK
Surya N
Fact-checked by Surya N
Published on: 2 Jun 2026Last updated: 16 Jun 2026
Share: