Progressive Web Applications (PWAs) represent a fundamental shift in how users experience web content. By blending the reach of the web with the capabilities of native mobile apps, PWAs deliver fast, reliable, and engaging experiences that work across all modern browsers. Using JavaScript frameworks like React, Vue, and Angular, developers can leverage powerful tooling to add PWA features such as offline support, push notifications, and installability without rewriting an entire codebase. This guide provides a production-ready approach to building a PWA with popular JavaScript frameworks, covering everything from architecture decisions to deployment.

Understanding the Core Components of a PWA

A Progressive Web App is more than just a responsive website. At its core, a PWA must satisfy three technical requirements: a service worker for caching and offline behavior, a web app manifest for installability, and a secure HTTPS connection. Beyond these, a PWA should also be responsive, work offline or on low-quality networks, and provide a native-like user experience. The service worker acts as a programmable proxy between the browser and the network, enabling caching strategies, background sync, and push notifications. The manifest is a JSON file that tells the browser how the app should behave when installed on a device.

JavaScript frameworks simplify the most complex part—service worker implementation—by providing abstractions and build tools. Understanding these three pillars is essential before choosing a framework.

Choosing the Right JavaScript Framework for Your PWA

Every major JavaScript framework offers first-class or plugin-based PWA support. The best choice depends on your team’s familiarity, project requirements, and the deployment environment.

React with Create React App

React’s Create React App (CRA) includes a built-in service worker via serviceWorkerRegistration.js. For a production-grade PWA, developers often switch from the default to Workbox for more control over caching and precaching. CRA also generates a basic manifest.json automatically. For new projects, consider using Next.js (a React framework) which offers full PWA support through the next-pwa plugin, combining server-side rendering with progressive enhancement.

Vue.js with Vue CLI

Vue CLI provides the @vue/cli-plugin-pwa plugin that integrates Workbox directly. After running vue add pwa, you get a configured service worker and manifest. Vue’s simplicity and reactive data model make it an excellent choice for PWAs that require smooth transitions and reactive UI updates, even offline.

Angular with Angular Service Worker

Angular has the most mature built-in PWA support. The Angular service worker is tightly integrated with the Angular CLI and router, offering automatic caching of static assets and data groups. Running ng add @angular/pwa adds the necessary files and a preconfigured ngsw-config.json. Angular’s service worker is designed for large-scale applications and handles complex caching scenarios out of the box.

Other frameworks such as Svelte and Solid also have excellent PWA tooling, but for this guide we will focus on the three most widely adopted frameworks.

Setting Up Your PWA Project

Begin by scaffolding a new project with your chosen framework. Below are the exact commands and first steps for each.

React (Create React App)

npx create-react-app my-pwa
Inside src, locate serviceWorkerRegistration.js. By default, the service worker is unregistered. To enable production precaching, open src/index.js and change serviceWorkerRegistration.unregister() to serviceWorkerRegistration.register(). For custom caching logic, install Workbox: npm install workbox-webpack-plugin and configure it in config/webpack.config.js (after ejecting) or use the craco-workbox plugin without ejecting.

Vue.js (Vue CLI)

vue create my-pwa (select default preset or manually choose features).
Then add the PWA plugin: vue add pwa. This creates a public/manifest.json and a src/registerServiceWorker.js file. The default configuration uses Workbox and caches all static assets. You can customize caching in vue.config.js under the pwa property.

Angular

ng new my-pwa (include routing for ease).
Add PWA support: ng add @angular/pwa. This command generates manifest.webmanifest, ngsw-config.json, and registers the service worker in app.module.ts. Angular’s service worker works with the CLI’s build system automatically, requiring minimal manual configuration.

Adding PWA Features with Framework-Specific Tools

Once the project is scaffolded, the next step is to enable core PWA capabilities: service worker registration, offline caching, and the manifest configuration.

Registering the Service Worker

In React, the registration is handled by serviceWorkerRegistration.js. You can track the service worker’s lifecycle by listening to onUpdate and onSuccess callbacks to prompt users to refresh. For Vue, the registerServiceWorker.js file exposes similar hooks. In Angular, registration is automatic; you can inject SwUpdate from @angular/service-worker to listen for updates. Always ensure the service worker file is served from the root of your domain for proper scope.

Caching Strategies and Offline Support

Offline support is the hallmark of a PWA. Choose a caching strategy that matches your app’s data needs:

  • Cache-first (static assets): Serve cached files instantly, fall back to network if not found. Ideal for JavaScript bundles, CSS, and fonts.
  • Network-first (API calls): Try the network first, then fall back to cache. Best for dynamic content like user profiles.
  • Stale-while-revalidate: Serve cached content immediately and update the cache from the network. Perfect for news feeds or listings.

For React and Vue, the Workbox library (workbox-precaching and workbox-routing) lets you define these strategies declaratively. In Angular, the ngsw-config.json file uses a similar declarative approach with “assetGroups” and “dataGroups”.

Example: a Vue project can add a custom strategy in vue.config.js:

pwa: { workboxOptions: { runtimeCaching: [{ urlPattern: /api/, handler: 'NetworkFirst', options: { cacheName: 'api-cache' } }] } }

For React, a Workbox-based service worker snippet:

workbox.routing.registerRoute( new RegExp('https://api.example.com'), new workbox.strategies.NetworkFirst() );

Angular’s ngsw-config.json data group example:

{ "name": "api", "urls": ["/api/*"], "cacheConfig": { "strategy": "performance" } }

Configuring the Web App Manifest

The web app manifest tells the browser how your PWA should appear and behave when installed on a device. Customize these fields in public/manifest.json (React/Vue) or src/manifest.webmanifest (Angular):

  • name and short_name – The app name shown on the home screen.
  • icons – An array of icon objects with src, sizes, and type. Provide at least 192x192 and 512x512.
  • start_url – The root URL that opens when the launched app.
  • display – Use standalone to hide browser chrome. Other values: fullscreen, minimal-ui, browser.
  • theme_color and background_color – Control the splash screen and status bar color.
  • orientation – Optional, e.g., portrait-primary.

Ensure all icon paths are correct relative to the manifest location. Use tools like RealFaviconGenerator to generate icons and a maskable icon for Android. Angular users can add the maskable icon property directly in the manifest file; React and Vue users can define it via a purpose field in the icon object (e.g., "purpose": "any maskable").

Testing PWA Compliance

Before deployment, audit your PWA using automated tools. The Lighthouse tool in Chrome DevTools is the industry standard. Run an audit on your local build (use npm run build then serve it locally). Lighthouse checks for:

  • Service worker registration and scope
  • Manifest presence and valid icon sizes
  • HTTPS (localhost is exempt during development)
  • Offline start URL (click the “Offline” checkbox in DevTools to simulate)
  • Performance metrics like First Contentful Paint and Time to Interactive

Fix any failing audits. Common issues include missing maskable icons, incorrect cache headers, or service worker scope that does not cover the entire app. Use the Web Dev PWA learning path for deeper debugging.

Additionally, test on real devices: Android via Chrome, iOS via Safari (note: Apple’s PWA support is more limited but improving). For iOS, ensure you have a valid apple-touch-icon and meta[name="apple-mobile-web-app-capable"] in the for standalone display.

Deploying Your PWA

PWAs require HTTPS to install and use service workers. Use a deployment platform that provides automatic SSL, such as:

  • Vercel – Great for Next.js and React projects, offering automatic HTTPS.
  • Netlify – Supports Vue, React, and Angular builds with instant rollbacks and form handling.
  • Firebase Hosting – Fully integrated with Cloud Functions for backend logic.
  • GitHub Pages – Free but requires manual HTTPS certificate (via Cloudflare or enabling “Enforce HTTPS” in repository settings).

Enable push notifications to enhance user engagement. This requires a VAPID key and a back-end service to send push events. Frameworks like Firebase Cloud Messaging (FCM) streamline this. Remember that notifications must be explicitly granted by the user and must include meaningful content.

Monitor your PWA after launch using Google Analytics 4 or Web Vitals library to track real user metrics like Largest Contentful Paint and Cumulative Layout Shift. The Lighthouse extension can also audit a live URL.

Common Pitfalls and Best Practices

Building a PWA is straightforward, but certain mistakes can undermine performance and reliability:

  • Over-caching dynamic content – Cache API responses with a network-first strategy and short-lived caches, otherwise users may see stale data.
  • Ignoring update flow – When the service worker updates, notify users (e.g., “New version available. Refresh to update?”). Use the onUpdate callback in your framework.
  • Serving the service worker with wrong headers – Ensure the service worker file is served with Content-Type: text/javascript and never cached by the browser (set Cache-Control: no-cache).
  • Missing fallback for offline – Provide an offline page or a toast message so users are not left with a white screen.

For a comprehensive checklist, review the Web Dev PWA checklist.

Conclusion

Progressive Web Apps have matured into a viable alternative to native mobile development, and JavaScript frameworks provide the fastest path to production. By understanding the core components—service workers, web app manifest, and HTTPS—and leveraging framework-specific tools like Workbox for React/Vue and Angular’s native service worker, you can deliver a fast, reliable, installable experience that works offline. Start with the scaffolding commands, configure caching strategically, and test rigorously with Lighthouse. Once deployed, iterate on performance and push notifications to keep users engaged. The PWA ecosystem is constantly evolving, so stay current with updates from your framework’s ecosystem and the broader web platform.