The ways of Workbox

Workbox is flexible enough to accommodate just about any project's build process. This means there's more than one way to use Workbox, allowing you to choose the right integration for your project. Regardless of how you integrate with Workbox, the various tools offer a similar API.

generateSW versus injectManifest

You'll rely on one of two core methods of Workbox's build tools: generateSW or injectManifest. Which one you should use depends on how much flexibility you need. generateSW prioritizes ease of use and simplicity at the cost of flexibility, allowing you to declare a set of configuration options and giving you a fully functional service worker in return.

injectManifest favors greater flexibility at the cost of some simplicity, since you'll end up writing the code for your service worker yourself, with injectManifest providing a precache manifest that can be used by Workbox's precaching methods.

When to use generateSW

You should use generateSW if:

  • You want to precache files associated with your build process, including files whose URLs contain hashes that you might not know ahead of time.
  • You have simple runtime caching needs that can be configured via generateSW's options.

When not to use generateSW

On the other hand, you should not use generateSW if:

  • You want to use other service worker features (such as Web Push).
  • You need additional flexibility to import additional scripts or use specific Workbox modules to fine-tune your service worker to your application's needs.

When to use injectManifest

You should use injectManifest if:

  • You want to precache files, but want to write your own service worker.
  • You have complex caching or routing needs that can't be expressed via generateSW's configuration options
  • You would like to use other APIs in your service worker (such as Web Push).

injectManifest differs from generateSW in that it requires you to specify a source service worker file. In this workflow, the source service worker file needs to have a special self.__WB_MANIFEST string in it so that injectManifest can replace it with the precache manifest.

When not to use injectManifest

You shouldn't use injectManifest if:

  • You don't want to use precaching in your service worker.
  • our service worker requirements are simple enough to be covered by what generateSW and its configuration options can provide.
  • You prioritize ease of use over flexibility.

Use Workbox's Build tools

If you're looking for a framework-agnostic way to use Workbox in your build process, you have three options:

  1. workbox-cli
  2. workbox-build. command line tool.
  3. Using a bundler (such as workbox-webpack-plugin).

Each of these build tools offers both the generateSW and injectManifest modes, with a similar set of options. These are all fine choices when you don't want to tie your Workbox-powered service worker to a particular framework. In order to know which of these options is the best fit, let's take a quick look at each one.

workbox-cli

If you're looking for the lowest possible barrier to entry with Workbox, the CLI is for you:

npm install workbox-cli --save-dev

To start using the CLI, run the wizard with npx workbox wizard. The wizard will ask a few questions, and the answers to those questions will be used to set up a project with a workbox-config.js file that you can customize to suit your needs. It will look something like:

// A config for `generateSW`
export default {
  globDirectory: 'dist/',
  globPatterns: [
    '**/*.{css,woff2,png,svg,jpg,js}'
  ],
  swDest: 'dist/sw.js'
};

Once your configuration file has been created, the CLI can run either generateSW or injectManifest methods for you. The CLI's help text has more information and examples of usage.

workbox-build

workbox-cli is a wrapper around the workbox-build module, and an alternative is to use workbox-builddirectly. When using workbox-build, instead of specifying options using a workbox-config.js file, you'll use the generateSW or injectManifest methods directly as part of a Node script, passing in a similar set of options:

// build-sw.mjs
import {generateSW} from 'workbox-build';

generateSW({
  globDirectory: 'dist/',
  globPatterns: [
    '**/*.{css,woff2,png,svg,jpg,js}'
  ],
  swDest: 'dist/sw.js'
});

In the above example, workbox-build will write the generated service worker to the dist directory when the node build-sw.mjs command is run.

Using a bundler

Various bundlers have their own Workbox plugins, but the only bundler officially supported by the Workbox team is webpack, via workbox-webpack-plugin. Like workbox-cli and workbox-build, workbox-webpack-plugin will run the generateSW or injectManifest methods, except the plugin capitalizes those method names as GenerateSW or InjectManifest. Otherwise, the usage is similar to workbox-build:

// webpack.config.js
import {GenerateSW} from 'workbox-webpack-plugin';

export default {
  // Other webpack config options omitted for brevity...
  plugins: [
    new GenerateSW({
      swDest: './dist/sw.js'
    })
  ]
};

The options you pass to either GenerateSW or InjectManifest aren't the same as generateSW or injectManifest, but there's significant overlap. In particular, you don't need to—nor can you—specify a globDirectory option for GenerateSW as webpack already knows where your production assets are bundled.

Use a framework

Everything covered up this point focuses on using Workbox regardless of one's framework preferences. However, it's possible to use Workbox within a specific framework if it makes development easier. For example, create-react-app ships with Workbox by default. Different framework integrations with Workbox are covered later in a later article.

It's worth noting that these framework-specific integrations of Workbox may restrict your ability to configure Workbox in the way you want. In cases like these, you can always fall back to the methods discussed here.

What if I don't have a build process?

This document assumes your project has a build process, but your project, in fact, may not. If that describes your situation, it's still possible to use Workbox with the workbox-sw module. With workbox-sw, you can load the Workbox runtime from a CDN or locally, and compose your own service worker.

Conclusion

Workbox's flexibility ensures that you can use it in just about any project, regardless of its framework or toolchain preferences. All of these avenues will allow you to accomplish precaching and runtime caching using a couple of methods, while allowing greater flexibility to build service workers with more advanced features when needed.