The Nuxt PWA module is one config entry that produces a service worker and a manifest
Zero-config PWA Plugin for Nuxt 3
At a glance
- What is it?
- @vite-pwa/nuxt is the Nuxt 3 module from the vite-pwa project that generates a Workbox service worker and a web app manifest from a single pwa block in nuxt.config.ts, with dev tooling for the service worker and an assets generator. It suits a Nuxt team that wants offline support without hand wiring a plugin, and the version floor it set will rule out some codebases.
- Who is it for?
- The Nuxt module fits a team on Nuxt 3.9 or later with Vite 5 that wants a service worker, a manifest and an installable app without writing the Workbox configuration by hand, and it fits a team that wants the service worker to be debuggable while it is being written.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 169 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the module actually adds to a Nuxt app
The package describes itself as a zero-config PWA plugin for Nuxt 3, and the core claim is that you get a working progressive web app by adding one module and one config block.
The feature list is specific about what that means. It generates a service worker with offline support via Workbox, it auto injects the Web App Manifest, and it configures static assets for offline support. It is written in TypeScript, described as type strong, and it is fully tree shakable.
The behaviour around new content is the part that decides whether a PWA is worth having. The stale-while-revalidate strategy gives automatic reload when new content is available, which is the mechanism that makes an installed app feel current rather than stale. Without it, an installed site shows old content forever and users reinstall or abandon it.
The prompt for new content support covers the common frontend stacks: Vanilla JavaScript, Vue 3, React, Svelte, SolidJS and Preact. That list is about how the plugin asks the browser to refresh, and it tells you the plugin is not tied to a rendering strategy.
The homepage is the framework page of the vite-pwa documentation site, and the whole project is broader than Nuxt: the same feature list names îles, SvelteKit, VitePress, Astro, Nuxt 3 and Remix as integrations.
Install and configure, and the version floor that decides
The install is a single command that uses the Nuxt CLI to add the module.
npx nuxi@latest module add @vite-pwa/nuxtAnd the configuration is one entry in nuxt.config.ts.
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt/config'
export default defineNuxtConfig({
modules: [
'@vite-pwa/nuxt'
],
pwa: {
/* PWA options */
}
})The requirement note is where a lot of adoption decisions get made. From v0.4.0, the module requires Vite 5 and Nuxt 3.9.0 or later, and for older versions it requires Vite 3.2.0 or later and Nuxt 3.0.0 or later.
So there is a floor, and the floor moved. A team on Nuxt 3.5 with Vite 4 can use an older release of the module, but a team that wants the current one is looking at a Nuxt upgrade. The zero-config promise is real, but it is not free of a version requirement, and that is worth checking before anything else.
The configuration block is deliberately empty in the example. The plugin is extensible and exposes the full ability to customize the behavior of the plugin, and the complete guide lives in the framework documentation, with the type declaration at src/types.ts as the reference for what the options are.
Debugging a service worker while you write it
The development support feature is the one that changes how you work with the module, and it deserves more attention than it usually gets.
The plugin gives you debug support for your custom service worker logic as you develop your application. A service worker is unusual in the browser platform because it is a second, separate program with its own lifecycle, it does not share the page's source, and a mistake in it produces failures that are invisible in the page's console. A module that lets you step through your service worker logic while the app is running removes the worst part of working with one.
There is also a second development facility, for the assets. The PWA Assets Generator generates all the PWA assets from a single command and a single source image, and the PWA Assets Integration serves, generates and injects PWA Assets on the fly in your application.
That combination addresses a real annoyance. A PWA needs icons in several sizes, a maskable icon variant, a splash screen set for different devices, and often a screenshot set for the install prompt. Producing those by hand is tedious and inconsistent. Generating them from one source image and injecting them at build time removes the tedium, and the on-the-fly serving means the asset set stays in step with the application rather than living in a folder someone updates once.
The remaining caveat is the one that applies to any asset pipeline: the generator decides the sizes, and if the install prompt on a particular platform needs a variant the generator does not produce, you will still be editing files by hand.
The example playground shows the two deployment shapes
The README explains that to see the PWA in action you need to stop the dev server once started, and then run one of two commands.
- `nr dev:preview:build`: Nuxt build command + start server - `nr dev:preview:generate`: Nuxt generate command + start server
Those two lines are more informative than they look, because they are the two deployment models a Nuxt app has and they behave differently for a service worker.
The build path produces a Node server, and the generate path produces static output. A service worker is a network request interceptor, so in the generated case it has to be served by whatever static host you use, with the right headers and scope. In the server case it is served by your own server. The plugin supports both, and the package.json has separate scripts for it, including dev:generate:netlify and dev:generate:vercel with the corresponding Nitro presets set.
The playground is a Nuxt app in the repository, with a playground-assets/ directory beside it for the asset generation example, and the README links a StackBlitz fork of it under the Auto Update PWA example, so you can click through the behaviour in a browser without setting anything up locally.
The package.json also shows the module's own toolchain: nuxt-module-build for the prepack and prepare steps, pnpm as the package manager, and a pnpm-lock.yaml with a pnpm-workspace.yaml, so the playground and the assets playground are workspace members rather than separate checkouts.
The repository is a Nuxt module template, not a bare plugin folder
The tree shows a project that follows the Nuxt module conventions, and understanding that tells you where the extension points are.
There is a src/ directory for the module source, a configuration.d.ts at the root, an eslint.config.js, a tsconfig.json, and a vitest.config.mts with a test/ directory and a client-test/ directory. The playwright.config.ts is there for end-to-end tests, which for a service worker plugin is the only way to test the parts that matter, since the interesting behaviour happens in a browser with a real service worker lifecycle.
The package.json describes the published shape. The package name is @vite-pwa/nuxt, the type is module, and the exports map has a root entry pointing at dist/module.mjs with types at dist/types.d.mts, a ./configuration entry with its own type declaration, and a catch-all ./* export. The files array ships only the declaration files and dist, and the typesVersions field maps the configuration subpath for older TypeScript resolution modes.
The author is Anthony Fu, and the funding field points at his sponsors page. The licence is MIT, and the README states it as MIT License, copyright 2023 to the present, Anthony Fu.
That the module is authored by someone whose main work is the vite-pwa ecosystem itself is the relevant point for an adopter: the framework module and the underlying Vite plugin come from the same project, so the options exposed in the pwa block are the ones the plugin actually supports rather than a curated subset.
Where a Nuxt app should not reach for this
There is a clear case against, and it is not about the quality of the module.
If your application is not served over HTTPS, a service worker will not register at all, and no configuration in the pwa block changes that. A PWA is also a commitment: once a service worker is installed, it holds a cache, and the update story becomes your problem. If your team has no plan for cache invalidation, the stale-while-revalidate behaviour will serve old content to a user who cannot force a refresh, and that is a worse outcome than a plain site.
The other wrong-tool case is an application that is mostly an authenticated application shell behind a login. The offline support Workbox gives you is precaching of your application assets, and the offline experience for a user who is not signed in is a login page that cannot reach the server. That is not a failure of the module, it is a mismatch between a PWA and an app that needs a live session.
And the pragmatic alternative deserves naming: Nuxt has its own routes and data fetching, and many Nuxt applications that want an installable experience are better served by an app manifest and a couple of meta tags without a service worker at all. That gives the install prompt and the standalone display without the cache lifecycle, the update prompts, and the debugging burden that comes with a worker running separately from the page.
The module is the right choice when offline support is a requirement, not a checkbox. If it is a checkbox, the manifest alone is usually the better trade.
Editorial conclusion
The Nuxt module fits a team on Nuxt 3.9 or later with Vite 5 that wants a service worker, a manifest and an installable app without writing the Workbox configuration by hand, and it fits a team that wants the service worker to be debuggable while it is being written. It does not fit a project on an older Nuxt, since the module requires Nuxt 3.9.0 and Vite 5 from v0.4.0, and it does not fit a site that needs a service worker behaviour Workbox cannot express, because the plugin exposes the underlying configuration rather than replacing it. Before adopting it, read the framework documentation for the options you intend to change, because the defaults are described as sensible for common use cases rather than as a specification, and check the manifest and asset handling, since a PWA that installs with the wrong icons and name is a worse outcome than no PWA at all.
Frequently asked questions
How do I install the Nuxt PWA module?
Run npx nuxi@latest module add @vite-pwa/nuxt, then add the module to the modules array in nuxt.config.ts and configure the pwa block. The project documentation has the full guide at the Nuxt page of the vite-pwa docs.
Which Nuxt and Vite versions does @vite-pwa/nuxt need?
From v0.4.0 the module requires Vite 5 and Nuxt 3.9.0 or later. Older module versions require Vite 3.2.0 or later and Nuxt 3.0.0 or later.
What does @vite-pwa/nuxt generate for my app?
A service worker with offline support generated via Workbox, an auto injected Web App Manifest, and configured static assets for offline support, with stale-while-revalidate for automatic reload when new content is available.
Can I see the PWA working during development?
Yes. The repository has scripts for it, and the README says to stop the dev server and then run nr dev:preview:build for the Nuxt build command plus server, or nr dev:preview:generate for the generate command plus server. The plugin also supports debugging your custom service worker logic as you develop.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vite-pwa-nuxt)