Didn't make the #ChromeDevSummit this year? Catch all the content (and more!) in the Chrome Dev Summit 2019 playlist on our Chrome Developers YouTube Channel.

Workbox CLI

What's the Workbox CLI?

The Workbox command line interface (contained in the workbox-cli package) consists of a Node.js program called workbox that can be run from a Windows, macOS, of UNIX-compatible command line environment. Under the hood, workbox-cli wraps the workbox-build module, and provides an easy way of integrating Workbox into a command line build process, with flexible configurations.

Install the CLI

Installing the CLI is simple, just run the following command in your terminal.


npm install workbox-cli --global


yarn global add workbox-cli

CLI Modes

The CLI has four different modes:

  • wizard: A step-by-step guide to set up Workbox for your project.
  • generateSW: Generates a complete service worker for you.
  • injectManifest: Injects the assets to precache into your project.
  • copyLibraries: Copy the Workbox libraries into a directory.


The Workbox wizard asks a series of questions about your local directory setup and which files you want precached. Your answers are used to generate a configuration file which can then be used when running in generateSW mode.

Most developers will only need to run workbox wizard once, and you're free to manually customize the initial configuration file that's generated, using any of the supported build configuration options.

To start the wizard run:

workbox wizard

Screenshot of Workbox CLI's wizard


You can use the Workbox CLI to generate a complete service worker using a configuration file (like the file generated by the wizard.)

Just run the following command:

workbox generateSW path/to/config.js

Developers who are happy with Workbox's built-in precaching and runtime caching capabilities, and don't need to customize their service worker's behavior are recommended to use generateSW mode.

When to use generateSW

  • You want to precache files.
  • You have simple runtime configuration needs (e.g. the configuration allows you to define routes and strategies).

When NOT to use generateSW

  • You want to use other Service Worker features (i.e. Web Push).
  • You want to import additional scripts or add additional logic.


For developers who want more control of their final service worker file can use the injectManifest mode. This mode assumes that you have an existing service worker file (the location of which is specified in config.js).

When workbox injectManifest is run, it looks for a specific string (precaching.precacheAndRoute([]) by default) in your source service worker file. It replaces the empty array with a list of URLs to precache and writes the service worker file to its destination location, based on the configuration options in config.js. The rest of the code in your source service worker is left untouched.

You can use Workbox in this mode like so:

workbox injectManifest path/to/config.js

When to use injectManifest

  • You want more control over your service worker.
  • You want to precache files.
  • You have more complex needs in terms of routing.
  • You would like to use your service worker with other API's (e.g. Web Push).

When NOT to use injectManifest

  • You want the easiest path to adding a service worker to your site.


This mode is helpful if you would like to use injectManifest and would like to use the Workbox library files hosted on your own origin instead of using the CDN.

You just need to run it with a path to write the files to:

workbox copyLibraries third_party/workbox/

Build Process Integration

Why Does Workbox need to Integrate with My Build Process?

The Workbox project contains a number of libraries that work together to power your web app's service worker. In order to use those libraries effectively, Workbox needs to be integrated into your web app's build process. This ensures that your service worker is able to efficiently precache all of your web app's critical content, and keep that content up to date.

Is workbox-cli the Right Choice for My Build Process?

If you have an existing build process that is based entirely on npm scripts, then the workbox-cli is a good choice.

If you're currently using webpack as your build tool, then using the workbox-webback-plugin is a better choice.

If you're currently using Gulp, Grunt, or some other Node.js-based build tool, then integrating workbox-build into your build script is a better choice.

If you don't have a build process at all, then you should come up with one before using Workbox to precache any of your assets. Trying to remember to run workbox-cli manually can be error-prone, and forgetting to run it can lead to stale content being served to returning visitors.

Setup and Configuration

After installing workbox-cli as a development dependency for your local project, you can add the call to workbox at the end of your existing build process's npm script:

From package.json:

  "scripts": {
    "build": "my-build-script && workbox <mode> <path/to/config.js>"

Replace <mode> with generateSW or injectManifest (depending on your use case) and <path/to/config.js> with the path to your configuration options. Your configuration might have been created automatically by workbox wizard or tweaked manually.


Options used by generateSW

Below is a list of options used by just the generateSW command.

These options only apply to generateSW.


Optional String, defaulting to 'cdn'

Valid values are 'cdn', 'local', and 'disabled.

  • 'cdn', the default, will use a URL for the Workbox runtime libraries hosted on a highly-available Google Cloud Storage instance.
  • 'local' will copy all of the Workbox runtime libraries into a versioned directory alongside your generated service worker, and configure the service worker to use those local copies. This option is provided for developers who would prefer to host everything themselves and not rely on the Google Cloud Storage CDN.
  • 'disabled' will opt-out automatic behavior. It's up to you to host a local copy of the Workbox libraries at your preferred URL, and to pass in the correct path to workbox-sw.js via the importScripts configuration option.
  • Note: In webpack, passing in a string corresponding to the webpack chunk name containing a custom Workbox runtime library bundle is also supported.


importWorkboxFrom: 'local'


Optional Boolean, defaulting to false

Whether or not the service worker should skip over the waiting lifecycle stage.

When false, the generated service worker will automatically contain the following code:

self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'SKIP_WAITING') {

This allows your web app to trigger skipWaiting() on demand, by using postMessage() to communicate with your service worker. For more information about this technique, see this recipe.


skipWaiting: true


Optional Boolean, defaulting to false

Whether or not the service worker should start controlling any existing clients as soon as it activates.


clientsClaim: true


Optional Array of Object, defaulting to []

Passing in an array of objects containing urlPatterns, handlers, and potentially options will add the appropriate code to the generated service worker to handle runtime caching.

Requests for precached URLs that are picked up via globPatterns are handled by default, and don't need to be accommodated in runtimeCaching.

The handler values are strings, corresponding to names of the strategies supported by workbox.strategies.

The options properties can be used to configure instances of the cache expiration, cacheable response, and broadcast update plugins to apply to a given route.


runtimeCaching: [{
    // Match any same-origin request that contains 'api'.
    urlPattern: /api/,
    // Apply a network-first strategy.
    handler: 'NetworkFirst',
    options: {
      // Fall back to the cache after 10 seconds.
      networkTimeoutSeconds: 10,
      // Use a custom cache name for this route.
      cacheName: 'my-api-cache',
      // Configure custom cache expiration.
      expiration: {
        maxEntries: 5,
        maxAgeSeconds: 60,
      // Configure background sync.
      backgroundSync: {
        name: 'my-queue-name',
        options: {
          maxRetentionTime: 60 * 60,
      // Configure which responses are considered cacheable.
      cacheableResponse: {
        statuses: [0, 200],
        headers: {'x-test': 'true'},
      // Configure the broadcast update plugin.
      broadcastUpdate: {
        channelName: 'my-update-channel',
      // Add in any additional plugin logic you need.
      plugins: [
        {cacheDidUpdate: () => /* custom plugin code */}
      // matchOptions and fetchOptions are used to configure the handler.
      fetchOptions: {
        mode: 'no-cors',
      matchOptions: {
        ignoreSearch: true,
  }, {
    // To match cross-origin requests, use a RegExp that matches
    // the start of the origin:
    urlPattern: new RegExp('^https://cors\.example\.com/'),
    handler: 'StaleWhileRevalidate',
    options: {
      cacheableResponse: {
        statuses: [0, 200]


Optional String, defaulting to undefined

This will be used to create a NavigationRoute that will respond to navigation requests for URLs that that aren't precached.

This is meant to be used in a Single Page App scenario, in which you want all navigations to use common App Shell HTML.

It's not intended for use as a fallback that's displayed when the browser is offline.


navigateFallback: '/app-shell'


Optional Array of RegExp, defaulting to []

An optional array of regular expressions that restricts which URLs the configured navigateFallback behavior applies to.

This is useful if only a subset of your site's URLs should be treated as being part of a Single Page App.

If both navigateFallbackBlacklist and navigateFallbackWhitelist are configured, the blacklist takes precedent.


// Exempt all URLs that start with /_ or contain admin anywhere:
navigateFallbackBlacklist: [/^\/_/, /admin/]


Optional Array of RegExp, defaulting to []

An optional array of regular expressions that restricts which URLs the configured navigateFallback behavior applies to.

This is useful if only a subset of your site's URLs should be treated as being part of a Single Page App.

If both navigateFallbackBlacklist and navigateFallbackWhitelist are configured, the blacklist takes precedent.


// Include URLs that start with /pages:
navigateFallbackWhitelist: [/^\/pages/]


Required Array of String

An required list of JavaScript files that should be passed to importScripts() inside the generated service worker file.

If one of the imported files sets the self.__precacheManifest variable to an array of ManifestEntrys, those entries will be automatically precached in the generated service worker.

This is also useful when you want to let Workbox create your top-level service worker file, but want to include some additional code, such as a push event listener.


importScripts: ['push-notifications.abcd1234.js']


Optional Array of RegExp, defaulting to [/^utm_/]

Any search parameter names that match against one of the regex's in this array will be removed before looking for a precache match.

This is useful if your users might request URLs that contain, for example, URL parameters used to track the source of the traffic. Those URL parameters would normally cause the cache lookup to fail, since the URL strings used as cache keys would not be expected to include them.


// This will ignore all parameters:
ignoreURLParametersMatching: [/./]


Optional String, defaulting to index.html

If a navigation request for a URL ending in / fails to match a precached URL, this value will be appended to the URL and that will be checked for a precache match.

This should be configured to whatever your web server is using, if anything, for its directory index.


directoryIndex: 'index.html'


Optional String, defaulting to null

An optional ID to be prepended to cache names used by Workbox.

This is primarily useful for local development where multiple sites may be served from the same http://localhost:port origin.


cacheId: 'my-app'


Optional Boolean, defaulting to false

Controls whether or not to include support for offline Google Analytics.

When true, workbox.googleAnalytics.initialize() will be added to your new service worker file.


offlineGoogleAnalytics: true


Optional Boolean, defaulting to false

Whether or not Workbox should attempt to identify an delete any precaches created by older, incompatible versions.


cleanupOutdatedCaches: true


Optional Boolean, defaulting to false

Whether or not to enable navigation preload in the generated service worker.

When set to true, you must also use runtimeCaching to set up an appropriate response strategy that will match navigation requests, and make use of the preloaded response.


navigationPreload: true,
runtimeCaching: [{
  urlPattern: ({event}) => event.request.mode === 'navigate',
  handler: 'NetworkOnly',

Options used by injectManifest

Below is a list of options used by just the injectManifest command.

These options only apply to injectManifest.


Required String

The path to the source service worker file that can contain your own customized code, in addition to containing a match for injectionPointRegexp.

In Node

Your service worker file should include a call to a workbox.precaching method that makes use of the injected precache manifest.

In Webpack

Your service worker file should reference the self.__precacheManifest variable to obtain a list of ManifestEntrys obtained as part of the compilation: workbox.precaching.precacheAndRoute(self.__precacheManifest)


swDest: path.join('src', 'sw.js')


Optional RegExp, defaulting to /(\.precacheAndRoute\()\s*\[\s*\]\s*(\))/

By default, the RegExp used will find the string precacheAndRoute([]) inside of your swSrc file, and replace the empty [] array with an array containing the ManifestEntrys that should be precached.

If you want the ManifestEntrys injected into a different part of your swSrc file, then configure this to be a different RegExp containing two capture groups. The manifest array will be injected in between the capture groups.


// Inject the manifest into a variable assignment:
injectionPointRegexp: new RegExp('(const myManifest =)(;)')

Options used by both

The remaining options are used by both commands.

Used by both generateSW and injectManifest.


Required String

The path and filename of the service worker file that will be created by the build process. In node, this will be relative to the current working directory. In webpack, this will be relative to the webpack output directory.


swDest: path.join('dist', 'sw.js')


Optional String, defaulting to undefined

The base directory you wish to match globPatterns against, relative to the current working directory.

If you do set this, make sure to also configure globPatterns.


// Treat all patterns as relative to the current directory:
globDirectory: '.'


Optional Boolean, defaulting to true

Determines whether or not symlinks are followed when generating the precache manifest.

For more information, see the definition of follow in the glob documentation.


globFollow: false


Optional Array of String, defaulting to ['node_modules/**/*']

A set of patterns matching files to always exclude when generating the precache manifest.

For more information, see the definition of ignore in the glob documentation.


globIgnores: ['**/ignored.html']


Optional Array of String, defaulting to either ['**/*.{js,css,html}'] (for workbox-build and workbox-cli) or [] (for workbox-webpack-plugin)

Files matching against any of these patterns will be included in the precache manifest.

For more information, see the glob primer.

Note: Setting globPatterns is often unnecessary when using the workbox-webpack-plugin, which will automatically precache files that are part of the webpack build pipeline by default. When using the webpack plugin, only set it when you need to cache non-webpack assets.


globPatterns: ['dist/*.{js,png,html,css}']


Optional Boolean, defaulting to true

If true, an error reading a directory when generating a precache manifest will cause the build to fail. If false, the problematic directory will be skipped.

For more information, see the definition of strict in the glob documentation.


globStrict: false


Optional Object with String or Array of String values, defaulting to null

If a URL is rendered generated based on some server-side logic, its contents may depend on multiple files or on some other unique string value.

If used with an array of strings, they will be interpreted as glob patterns, and the contents of any files matching the patterns will be used to uniquely version the URL.

If used with a single string, it will be interpreted as unique versioning information that you've generated out of band for a given URL.


templatedURLs: {
  '/app-shell': [
  '/other-page': 'my-version-info',


Optional Number, defaulting to 2097152

This value can be used to determine the maximum size of files that will be precached. This prevents you from inadvertantly precaching very large files that might have accidentally matched one of your patterns.


// Increase the limit to 4mb:
maximumFileSizeToCacheInBytes: 4 * 1024 * 1024


Optional RegExp, defaulting to null

Assets that match this regex will be assumed to be uniquely versioned via their URL, and exempted from the normal HTTP cache-busting that's done when populating the precache.

While not required, it's recommended that if your existing build process already inserts a [hash] value into each filename, you provide a RegExp that will detect those values, as it will reduce the amount of bandwidth consumed when precaching.


dontCacheBustURLsMatching: /\.\w{8}\./


Optional Object with String values, defaulting to null

A mapping of prefixes that, if present in an entry in the precache manifest, will be replaced with the corresponding value.

This can be used to, for example, remove or add a path prefix from a manifest entry if your web hosting setup doesn't match your local filesystem setup.

As an alternative with more flexibility, you can use the manifestTransforms option and provide a function that modifies the entries in the manifest using whatever logic you provide.


modifyURLPrefix: {
  // Remove a '/dist' prefix from the URLs:
  '/dist': ''


Optional Array of ManifestTransform, defaulting to null

One or more ManifestTransform functions, which will be applied sequentially against the generated manifest.

If modifyURLPrefix or dontCacheBustURLsMatching are also specified, their corresponding transformations will be applied first.


manifestTransforms: [
  // Basic transformation to remove a certain URL:
  (originalManifest) => {
    const manifest = originalManifest.filter(
      (entry) => entry.url !== 'ignored.html');
    // Optionally, set warning messages.
    const warnings = []; 
    return {manifest, warnings};