# pwa-starter: a Lit and Vite base for installable web apps

> pwa-starter is PWABuilder's opinionated starter codebase for Progressive Web Apps, built on Lit, Vite and Workbox. It removes boilerplate setup, but the stack choice is fixed for you.

**pwa-builder/pwa-starter** — Welcome to the PWABuilder pwa-starter! Looking to build a new Progressive Web App and not sure where to get started? This is what you are looking for!

- Repository: https://github.com/pwa-builder/pwa-starter
- Stars: 1,361 · Forks: 349
- Language: TypeScript
- License: NOASSERTION
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/pwa-builder-pwa-starter

## What the starter decides for you

pwa-starter is described as the PWABuilder team's opinionated, production tested starter that the team uses to build its own PWAs, including PWABuilder itself. The README positions it in the same family as create-react-app or the Angular CLI: a starter codebase you generate and then own. What you get is a set of choices already made, so the first commit of your app is application code rather than configuration.

The concrete choices are visible in package.json. The UI layer is lit at ^3.3.3, with @awesome.me/webawesome at ^3.10.0 for a component library and urlpattern-polyfill at ^10.1.0. The build is Vite at ^8.1.3 with TypeScript at ^7.0.2. Offline support comes from workbox-build, workbox-core and workbox-precaching at ^7.4.1, plus vite-plugin-pwa at ^1.3.0 in the dev dependencies. The primary language of the repository is TypeScript, and tsconfig.json sits at the top level.

That combination is the whole pitch. A Progressive Web App needs a manifest, a service worker, an install path and a build pipeline, and getting all four right before writing a feature is exactly the work this package front loads.

## No build system to set up, and nothing to add

The README lists what the generated app gives you, and the first bullet is the one that matters most for evaluation: no build system to set up and no boilerplate code to add, everything included out of the box. For a team that has never shipped an installable web app, that removes the part where the service worker registration, the manifest, and the asset precache list are wired together by hand.

The second point is the Service Worker system using Workbox. The precaching packages in package.json (workbox-precaching, workbox-core, workbox-build) are what let the service worker know which assets to cache ahead of time rather than fetching at runtime. The README also claims a Lighthouse score close to 100 out of the box, and states that everything needed for the app to be installable in the browser is already there.

That last claim deserves a caveat rather than acceptance. The README does not document a service worker update strategy, a cache versioning policy, or how precache entries behave when you deploy a new build. Those are decisions your team still owns, and the starter only removes the initial wiring.

## Creating an app through the pwa CLI

The README points to the full documentation at docs.pwabuilder.com under starter quick start, but the quick path is three commands. Install the PWABuilder CLI globally, create a template, and start it locally:

```bash
npm i -g @pwabuilder/cli
pwa create
pwa start
```

The first line installs @pwabuilder/cli from npm. The second generates a new app from the pwa-starter template. The third runs the app on a local server. The README describes it as all you need, and points to a video walkthrough for the same flow.

If you would rather work with the repository directly, the package.json scripts cover the same ground from inside the project. dev-server runs vite --open, dev is an alias for it, dev-task runs vite without opening a browser, start-remote runs vite --host to expose the server on the network, and build runs tsc followed by vite build:

```bash
npm run dev
npm run build
npm run start-remote
```

The build script is worth noting because it runs the TypeScript compiler before Vite, so type errors fail the build rather than being caught only in the editor.

## Azure Static Web Apps is the assumed deployment target

The generated project carries swa-cli.config.json at the top level, and the README says the starter uses the Azure Static Web Apps CLI, which enables emulating your production environment locally and gets you ready for deploying to Azure Static Web Apps. The deploy script in package.json runs the CLI in two steps, first a login and then a deploy:

```bash
npm run deploy
```

That script is npx @azure/static-web-apps-cli login --no-use-keychain followed by npx @azure/static-web-apps-cli deploy. The --no-use-keychain flag exists so the login does not write to the macOS keychain, which matters in CI where no keychain is present.

There is a second deployment path in the README, and it is the one that broadens the audience: the app is described as ready to be packaged for the app stores using PWABuilder. So the starter is opinionated about the local development and Azure hosting story, while the packaging step stays platform neutral.

If your deployment target is not Azure Static Web Apps, the swa-cli.config.json file and the deploy script are the two pieces you would replace. Nothing in the dependency list ties the application code to Azure.

## The custom licence is the first thing to check

The repository licence is recorded as a custom licence that GitHub cannot classify, and the file on disk is LICENSE.txt at the top level. That is not a nitpick for a starter, because a starter template is copied into every project that uses it, and the terms travel with the copy. Read that file before you generate your first app from it.

Inside package.json the package-level licence field reads ISC, which is a separate thing from the repository licence and reflects how the published package is marked rather than the terms you accept when you copy the template. The two do not obviously say the same thing, and the README does not explain the relationship.

The other maintenance signal is straightforward. The repository is not archived, and the last push was on 2026-07-16. There are no GitHub releases, so there is no version history in the releases list to track, and the package.json version field sits at 0.0.1. Upgrade cost therefore comes from the template rather than from tagged releases: you track the upstream template by comparing files, not by reading release notes.

## Where pwa-starter stops and your own code begins

The repository layout shows what you inherit and what you replace. At the top level sit index.html, global.css, tsconfig.json, vite.config.ts, swa-cli.config.json, and package.json, plus public/ and src/ directories and a .vscode/ folder. The source lives under src/, static assets under public/, and CI or contribution metadata under .github/.

The template also carries a Prettier configuration inside package.json, so formatting is fixed for you as well: two space indentation, semicolons on, single quotes, consistent quote props, trailing commas in es5 style, and CRLF line endings. The endOfLine setting of crlf is worth knowing about on a team that mixes operating systems, because it will rewrite files with Unix line endings on checkout.

The genuine limitation is not technical but structural. This is a template, not a framework, so every architectural decision about routing, state, data fetching and testing is yours from the first commit, and nothing in package.json suggests any of those are pre-installed. The Lit and Vite choice is baked in. A team that would rather write React components, or that needs a router, a state manager and a test runner configured to house rules, will find that this starter hands them a running PWA and then leaves them to build the application around it. That is a reasonable trade for a small team shipping a focused app, and a poor one for a team with settled house conventions.

## Conclusion

pwa-starter suits teams that want an installable PWA with a service worker already wired and prefer TypeScript and Lit, and it removes the setup decisions that usually eat a first week. It is the wrong starting point if your team writes React or Vue, if you want a different build tool, or if you need to support browsers the choice of Lit does not cover. Before adopting it, read LICENSE.txt, since the repository licence is a custom one that GitHub cannot classify, and confirm that the pinned Lit and Vite versions in package.json match your own upgrade policy.

## FAQ

### How do I create a new project with pwa-starter?

Install the PWABuilder CLI with npm i -g @pwabuilder/cli, then run pwa create to generate a template and pwa start to serve it locally. The README links the full documentation at docs.pwabuilder.com under starter quick start.

### Which framework does pwa-starter use?

The UI layer is lit at ^3.3.3 with @awesome.me/webawesome, built by Vite at ^8.1.3 and TypeScript at ^7.0.2. Offline support comes from the workbox packages at ^7.4.1 and vite-plugin-pwa at ^1.3.0.

### Can I deploy a pwa-starter app somewhere other than Azure?

The starter ships swa-cli.config.json and a deploy script that uses @azure/static-web-apps-cli, so that path assumes Azure Static Web Apps. The README also says the app is ready to be packaged for the app stores using PWABuilder.

### What licence does pwa-starter use?

The repository licence is a custom one that GitHub cannot classify, and the terms are in LICENSE.txt at the top level. The package.json licence field reads ISC, which is a separate field.

## Sources

- [Issues](https://github.com/pwa-builder/pwa-starter/issues)
- [pwa-builder/pwa-starter on GitHub](https://github.com/pwa-builder/pwa-starter)
- [README](https://github.com/pwa-builder/pwa-starter/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pwa-builder-pwa-starter
