Pam Lu Tech writer and factotum.

Setting up a PWA with service workers and create-react-app

3 min read 1066

Service workers and Create React App

This tutorial covers what you need to know about using service workers to build a progressive web app (PWA) with create-react-app (CRA). We’ll start by explaining PWAs, then discuss what a service worker is, and finally, review the steps to setting up service workers for a CRA.

About progressive web applications

A progressive web app is an enhanced type of web app that has some of the same capabilities as a native or platform-specific app.

For example, progressive web apps can be installed directly on a user’s home screen and can run in a standalone window. These apps run fast and reliably under poor network conditions and can even function offline.

Think of how your typical mobile user moves through changing environments while using your app. They might start out in a building that has a reliable high-speed network — great. Then they walk out to the street, where they lose wifi and fall back to cellular connectivity.

They might catch a strong 4G or even 5G signal … or they might hit a low-service dip that only has 3G. How can they stay on your app in all network conditions, even when they have no connectivity at all?

A progressive web app lets you reach your users wherever they are and serve them fast and reliable user experiences in any network environment.

What is a service worker?

A service worker is a special type of web worker that intercepts network requests from a web app and controls how these requests are handled. In particular, the service worker can manage the caching of resources and retrieval of these resources from the cache, thereby supporting the offline-first mode that’s crucial for PWAs.

Service workers provide essential support for running a progressive web application.

A service worker takes the form of a JavaScript file that runs in a separate, non-blocking thread from the main browser thread.

Recent versions of CRA come equipped with built-in support for the InjectManifest plugin from Workbox, which handles the compiling and injection of service workers into your app’s precaching list.

We made a custom demo for .
No really. Click here to check it out.

Setting up service workers for create-react-app


There are a couple of things you need to do before getting started:

  • Make sure you’re using create-react-app 4 or later
  • Make sure your production web server supports HTTPS

Tip: Service workers and progressive web app features will only run over HTTPS for security reasons. Users can still run your app over HTTP, but they won’t have access to offline-first mode and all the other great features made possible by service workers.

We’re ready now to dive into the setup process.

1.) Create a project and add a service-worker.js file

To leverage CRAs integration with Workbox’s InjectManifest plug-in, all you need to do is create a new project using a custom PWA template:

npx create-react-app my-app --template cra-template-pwa

The template automatically adds a src/service-worker.js file to your project. This file contains a basic service worker that you can come back to later and customize to your liking.

Or, if you prefer to write your app in TypeScript over JavaScript, here’s how you would create a project that includes a starter src/service-worker.js file:

npx create-react-app my-app --template cra-template-pwa-typescript

2.) Register the service worker

By default, service workers don’t become active and available for use until you register them. To learn more, you can read up on the fundamentals of the service worker life cycle.

Go to the src/index.js file in your project and find these lines:

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers:

To register the service worker for use, simply modify the last line so that it looks like this:


The src/service-worker.js file is now registered and ready to play its key role in providing an offline-first experience for your users.

3.) Customize the service worker

The starter src/service-worker.js file that you added using the cra-template-pwa or cra-template-pwa-typescript template comes with the basic logic for underpinning your progressive web app. If you want to expand the offline-first capabilities of your app, you can easily customize src/service-worker.js.

Tip: To support pre-caching, make sure that you assign the self.__WB_MANIFEST value to a variable that can be recognized by the InjectManifest plug-in. The plugin needs to see this value in order to generate its manifest of URLs for pre-caching.

Some examples of how you can customize the src/service-worker.js file include:

  • Using additional service worker packages from Workbox
  • Adding push notifications
  • Fine-tuning background data synchronization
  • Centralizing updates to shared geolocation or gyroscope data
  • Adding the ability to handle traffic originating from a different domain

As the Service Worker API continues to evolve, you can look forward to being able to support even more features and use cases with your PWAs.

4.) Help users navigate your progressive web app

Now that you’ve configured your project to support service workers, it’s time to make sure your users are ready and able to take full advantage of offline-first mode. Since progressive web apps behave a little differently from standard web apps, it’s a good idea to educate your users so that they can make the most of their experience.

You can help your users by showing in-app messages that remind them to:

  • Use a browser that supports service workers — like Chrome, Firefox, Opera, Samsung Internet, Safari, or Edge. (Note: service workers aren’t supported by any browser when in private or incognito mode).
  • Be aware of when the app is working offline. Once the service worker has initially populated the caches, show your users a message informing them that the app can now be used offline.
  • Close existing browser tabs to see the latest updates. By default, a service worker is kept on standby after it fetches content updates. As a result, users won’t be able to see the changes until after they close all open tabs and load a fresh page.


Turning your standard web app into a PWA is no sweat, thanks to create-react-app’s robust integration with Workbox. Once you set up service workers to support an offline-first user experience, your app will be able to reach more users on-the-go, wherever they happen to be.

Full visibility into production React apps

Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — .

Pam Lu Tech writer and factotum.

4 Replies to “Setting up a PWA with service workers and create-react-app”

  1. Hello… what if I already created the app without the templato. How can I add the same service-worker.js file to my project?

  2. I think you just need to add your file to the public folder and register it as you normally would then. The workbox stuff gets trickier though if you’re using that. There is a good walkthrough on making service workers with CRA on Udemy if you search there for `custom service worker CRA without ejecting`.

  3. Can a pwa not display latest updated build without closing and opening again?

Leave a Reply