# MDN pwa-examples: four small apps that show what a PWA actually needs

> The MDN pwa-examples repository is not a framework but a set of four deliberately small progressive web apps, each isolating one capability: local storage and caching in CycleTracker, installability in a2hs, offline play in a js13kGames entry, and window controls overlay in a custom titlebar. It is reference material for reading, and it is CC0 licensed so the code can be reused freely.

**mdn/pwa-examples** — Examples for progressive web apps.

- Repository: https://github.com/mdn/pwa-examples
- Stars: 1,016 · Forks: 619
- Language: JavaScript
- License: CC0-1.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/mdn-pwa-examples

## Four directories, one capability each

The repository listing is the documentation. There are four example directories and nothing else of substance: a2hs, custom-titlebar, cycletracker and js13kpwa, plus a CODE_OF_CONDUCT.md, a SECURITY.md, a LICENSE and the README.

That structure is the design decision. A PWA is not one API but a bundle of capabilities: a web app manifest for installability, a service worker for offline and caching, some way to store data on the device, and optionally push notifications. Each example takes one of those and nothing else, so a reader can see exactly what that capability requires and what it does not.

The README describes the four in enough detail to tell them apart, which is the part that makes the repository useful as reference material rather than as a pile of code.

CycleTracker is a basic app for tracking menstrual cycles, whose HTML includes a form to add period cycle start and end dates, and whose JavaScript sorts the dates and saves them to local storage, then displays the dates retrieved from local storage below the form. It also has a manifest file with three icons, a colour scheme and so on, and a service worker to handle asset caching.

That is a complete small application: input, persistence, display, installability, offline. It is the one example here that is an app rather than a demonstration of a single feature.

## a2hs is the smallest possible installable app

The a2hs example exists to show how Add to home screen works, and it is deliberately stripped down to the two files that matter.

It includes an icon and a manifest file, at a2hs/manifest.webmanifest, for allowing the app to be added to home screen, and a simple service worker, at a2hs/sw.js, for making the site work offline. There is a live version hosted on GitHub Pages at mdn.github.io/pwa-examples/a2hs/.

The point of the example is that installability is not a mystery. It is a manifest with the right fields and a service worker that caches the shell. A developer who has read about add to home screen without ever seeing the wiring can read these two files and understand the whole path.

The manifest being a.webmanifest file is the modern form, and the fact that the example provides the icon alongside it is a reminder that the icon is part of the manifest rather than decoration next to it.

What the example cannot show you is the part that decides whether users actually install. A manifest and a service worker make an app installable; they do not make it worth installing, and the difference is a product question the example is not about.

## js13kpwa: offline play as the demonstration

The js13kpwa directory holds a list of A-Frame entries submitted to the js13kGames 2017 competition, and they are used as an example for the MDN articles about Progressive Web Apps. The README is explicit about the four properties these entries have.

They have the App Shell structure. They work offline with the Service Worker. They are installable thanks to the Manifest file and Add to Homescreen feature. And they are re-engageable by using Notifications and Push.

Re-engageable is the term worth pausing on. It comes from the web app engagement model, and it is the property that a native app has and a web app historically did not: once installed on a home screen, the app can be brought back to the foreground by a notification rather than by the user finding and opening it. Push plus Notifications is what makes that possible, and the example demonstrates it in a game, which is a good place to demonstrate it because a game that notifies you to come back is a legible use case.

The App Shell concept is the other thing being shown. The idea is that the shell, the HTML, CSS and JavaScript that make up the interface, is cached and available offline, so the app starts instantly and works without a network, and the dynamic content is fetched around it.

These are 2017 entries, and that matters for anyone reading the code today. The APIs they use were experimental then and some have changed shape since, so the example is best read as illustrating the concepts rather than as a template to copy verbatim.

## custom-titlebar: the newest API in the set

The custom titlebar demo shows how to create a custom draggable app titlebar using window controls overlay features.

The README names the specific ingredients: the titlebar-area-* env() variables, and the window-drag property. The first gives the CSS environment variables that describe where the titlebar area is on the platform, and the second is the property that marks an element as draggable so the window can be moved by it.

That is the whole point of the window controls overlay API. When an app is installed, the platform draws its own title bar with the window controls, and on desktop that bar can be an awkward strip of unused space. With the overlay feature, the web app can draw its own content in that region and make it draggable, so an installed PWA looks like a native window rather than a page in a frame.

This is the most modern of the four examples and the one with the least documentation elsewhere, which is exactly why it is in the repository. There is a live version at mdn.github.io/pwa-examples/custom-titlebar/.

The limitation is inherent to the API. It is an install-time, platform-dependent feature, so the same code has to have a fallback for the browser tab, and a developer testing in a normal window will not see the behaviour at all.

## Local storage in CycleTracker, and why the example does it anyway

CycleTracker is the only example in the set with a data model, and the way it handles data is where the teaching value and the limitation sit together.

The app has a form to add a period cycle start and end dates. The JavaScript sorts the dates and saves them to local storage. The app also displays the dates retrieved from local storage below the form.

So the persistence is localStorage, the display is read back from the same place, and the sorting happens in the client before writing. There is no server, no account, and no sync. The result is a single-device diary that works offline, which is also why the service worker can cache the assets and the app still function with no network at all.

The trade-off is that the data lives on one device. Clearing site data, using a different browser, or moving to a new phone loses it, and there is no way to share or back up the history. For a demonstration of a form plus local storage plus offline, that is exactly right. For a real health record, it is not, and anyone adapting this example needs to decide where the data actually lives before reusing the pattern.

The manifest with three icons and a colour scheme is the other half of the offline story, since the installed icon and the theme colour are what make the app feel native once it is on the home screen.

## CC0 and GitHub Pages, and what the repository is not

The licence is CC0-1.0, which is worth pausing on because it is unusual for code. Creative Commons Zero is a public domain dedication with no attribution requirement, and the README notes that the examples are on GitHub Pages so you can read the live versions.

For a repository of example code, CC0 is a defensible choice. You can copy a file into your own project without a licence header and without owing anyone anything, which is exactly what you want from reference material. The code is not maintained as a library and carries no compatibility promise, so the usual reasons for a copyleft licence on a library, protecting a shared improvement, do not apply.

What the repository is not is worth stating as clearly as what it is. There is no build system, no package manager configuration, no test suite and no framework. Each example is a directory of static files, and the live deployments are served straight from GitHub Pages. The four directories are the entire content, and that is by design.

The last push was on 2026-10-06, and the repository has no GitHub releases, which is consistent with a set of examples that are revised in place rather than versioned. The SECURITY.md file is there for reporting a problem, and the CODE_OF_CONDUCT.md sets the expectations for the community around it.

The audience is a developer reading MDN documentation who wants to see a working version of the thing being described, and, in the case of the MDN articles themselves, the source of the live demos embedded in them.

## Conclusion

pwa-examples suits a developer who understands the individual PWA APIs but has not yet put them together in a running app, because each example isolates one capability and the whole repository can be read in an afternoon. It is the wrong tool as a starting point for a production application, since none of these examples addresses authentication, data sync, updates or testing, and the js13kpwa entries are A-Frame games submitted to a 2017 competition. Before you start from it, copy rather than depend, and check the local storage approach in cycletracker, because storing cycle data only on the device is a choice the example makes for illustration and one your own product may need to handle differently.

## FAQ

### What examples are in the MDN pwa-examples repository?

Four: cycletracker, a basic menstrual cycle tracking app using local storage with a manifest and a service worker; a2hs, a minimal example of Add to home screen with a manifest and a simple service worker; js13kpwa, A-Frame entries from the js13kGames 2017 competition; and custom-titlebar, a demo of the window controls overlay API.

### How does the a2hs example make a site installable?

It includes an icon and a manifest file at a2hs/manifest.webmanifest for allowing the app to be added to home screen, and a simple service worker at a2hs/sw.js for making the site work offline.

### Where does the CycleTracker example store its data?

In local storage. The JavaScript sorts the start and end dates and saves them to local storage, and the app displays the dates retrieved from local storage below the form.

### What does the custom-titlebar example demonstrate?

It shows how to create a custom draggable app titlebar using window controls overlay features, specifically the titlebar-area-* env() variables and the window-drag property.

### Can I reuse the code from MDN pwa-examples?

The repository is licensed CC0-1.0, a public domain dedication with no attribution requirement, so you can copy the example code into your own project freely.

## Sources

- [Issues](https://github.com/mdn/pwa-examples/issues)
- [License: CC0-1.0](https://github.com/mdn/pwa-examples/blob/main/LICENSE)
- [mdn/pwa-examples on GitHub](https://github.com/mdn/pwa-examples)
- [README](https://github.com/mdn/pwa-examples/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/mdn-pwa-examples
