If you'd like to turn the output of
create-react-app into a progressive web app (PWA) with offline support, take a look at the
create-react-pwa repo, and in particular, the GitHub diff of the minimal changes required.
create-react-app solves a problem that many folks (including I) have run into: how can you get started with a straightforward, client-rendered, single page React app and build process, without spending hours researching a list of (sometimes conflicting) dependencies to list in your
package.json? It's a project that came out of Facebook's React engineering a few months back, and has since gained some significant mindshare in the web developer community.
In keeping with the fewer-depencies-are-better-dependencies philosophy behind
create-react-app, the maintainers appear to be vigilant in the fight against scope creep, and are keeping the project lean. That's understandable, and it's left up to end users to decide what additional functionality to layer on top of the project's skeleton.
By design, the core of the build process isn't directly extensible. It's kicked off by
npm run build and consists of
"build": "react-scripts build"
But! The opportunity's there to cleanly chain some additional commands after that initial
react-scripts build, while keeping the
react-scripts black box opaque, giving us the chance to modify the output of the original build process.
That gets to the heart of my investigation: what's the easiest way to guide developers starting from a fresh
create-react-app towards the end goal of deploying a progressive web app? Specifically, what would it take to add in a service worker that provided performance benefits as well as a meaningful offline experience, as well as a web app manifest that contained application metadata?
This is just a standard JSON file with fields containing metadata useful for controlling the "add to homescreen" experience (currently only on Android devices). While each developer needs to choose their metadata wisely, there's nothing particularly challenging here from a technical perspective, and we just need to create the file and get it copied over to the
build/ output directory as part of the
npm run build process.
To handle the service worker, I (not surprisingly) turned to the
create-react-app output is local static files (there's no server-side rendering or remote API calls by default, for example),
sw-precache can handle everything we need with little configuration needed.
While I've traditionally used
gulp build process, it also sports a command-line interface, and it's simple to add in the
sw-precache command to the end of the
npm run build script chain.
Here's what the deployed PWA looks like on Chrome for Android, going through the steps of accepting the Add to Homescreen banner, and then launching it without a network connection.
The best way to visualize the changes to the build process, as well as the (small) modifications needed to the source code, is to view the GitHub diff between the starting point and the "final" PWA.
Take "final" with a grain of salt, because while you will end up with a build process that yields a progressive web app, there are many directions you might want to take the starter project, and some of those might entail a more complex service worker implementation. I've tried to cover some scenarios in the repo's README, including steps to take if you're using
react-router and need arbitrary URLs to work offline, as well as how you can add in runtime caching strategies for calls to third party APIs and resources.
If you're looking for examples of PWAs build with React that go a bit beyond what
create-react-app offers—for instance, that take advantage of server-side rendering or are built on third-party APIs—there are a few examples I could recommend: