# pwa-asset-generator: Automated PWA Icons, Splash Screens and Manifest Updates

> A TypeScript CLI that renders your logo or HTML through headless Chrome to produce iOS splash screens, Android icons, favicons and mstile images, then writes the matching manifest.json and index.html declarations.

**elegantapp/pwa-asset-generator** — Automates PWA asset generation and image declaration. Automatically generates icon and splash screen images, favicons and mstile images. Updates manifest.json and index.html files with the generated images according to Web App Manifest specs and Apple Human Interface guidelines.

- Repository: https://github.com/elegantapp/pwa-asset-generator
- Stars: 3,039 · Forks: 157
- Language: TypeScript
- License: MIT
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/elegantapp-pwa-asset-generator

## The two platform requirements pwa-asset-generator exists to satisfy

Android and iOS disagree about how a home screen icon and splash screen get declared. The README lays this out directly: Google's Android platform follows the Web App Manifest API and expects at least two icon sizes in the manifest file, while Apple's iOS does not support the Web App Manifest API at all. iOS instead wants a link tag with rel apple-touch-icon for the icon, and a link tag with rel apple-touch-startup-image for each splash screen resolution, each carrying a media attribute that encodes device width, device height, pixel ratio and orientation. The README quotes an example of that media query form and notes that Apple's Safari Web Content Guide does not document the requirement sufficiently. That asymmetry is the whole reason the tool exists. Doing it by hand means exporting a dozen or more splash images at exact pixel dimensions and hand-writing a media query for each one. The target user is a web developer shipping an installable PWA who already has a logo or an HTML page and does not want to open a design tool for every device class.

## Headless Chrome as an art board, and why the bundled device specs matter

The mechanism is unusual. Rather than resizing images with an image library, the tool uses Puppeteer to drive Chrome. According to the README, it builds a shell HTML page on the fly, uses it as an art board, centers your logo on it, and takes a screenshot at each target resolution. Puppeteer sits at the core of the project and the README states that this is what enables the rest of the feature set. The consequence is that the quality of the output depends on Chrome's renderer, not on a resampling algorithm, and that an HTML source can contain anything Chrome can draw: the README lists SVG filters, variable fonts, gradient backgrounds, media queries for dark mode splash screens and typography. An image source is simpler; it gets centered over the background you pass in. The second design decision is that device specs ship inside the package. The README says the tool works fully offline because the iOS and iPadOS specs are bundled, that Apple removed the device screen dimensions table from its Human Interface Guidelines, and that the bundled specs are therefore treated as the single source of truth. The --scrape flag is described as a deprecated no-op, which is a sensible outcome: scraping a spec page that no longer publishes the table would break silently.

## Installing pwa-asset-generator and generating a first set of assets

The package is on npm and requires Node.js >= 22.12.0, a constraint the README ties to puppeteer-core v25. A compatible Chrome or Chromium browser is needed, and the README says it is installed automatically on first use when needed. Install it as a dependency:

```bash
npm install pwa-asset-generator
```

For a one-off run without adding it to a project, the README gives npx:

```bash
npx pwa-asset-generator
```

The command signature is a source file followed by an output folder. The README states that assets are saved to the folder where the command is executed if no output folder is provided. The repository's own visual test scripts show the shape of a real invocation, using a logo file, an output directory, and flags for the background color and image type:

```bash
node ./bin/cli.js ./static/logo.svg ./src/__snapshots__/visual/input-svg -s false -b coral
```

Here -s false disables splash generation and -b coral sets the background. After a run you should see generated PNG files in the output folder, and if you pointed the tool at your project, updated link tags in index.html and icon entries in manifest.json. The README also documents --icon-only, --splash-only, --landscape-only and --portrait-only for narrowing the output, --favicon for classic web app icons and --mstile for Windows tiles.

## Tag formatting and path options are where real projects get stuck

Generated markup that points at the wrong URL is worse than no markup, and this is the part of the CLI worth reading closely before the first commit. The README lists --single-quotes for single-quoted attributes, --xhtml for self-closing tags, --path for a path prefix and --path-override for overriding paths entirely. That set exists because deployment layouts differ: a PWA served from a subdirectory, one that fingerprints assets through a bundler, and one that keeps images in a static folder all need different href values. The README frames these as options for complying with various development environments. The honest reading is that the tool writes into your source files, so the first run should happen on a branch or a copy. The README does not document a rollback command, and there is no dry-run flag mentioned in the options list, so the practical safeguard is version control rather than a built-in preview mode.

## Where pwa-asset-generator is the wrong tool

The dependency on a Chrome or Chromium binary is the sharpest limitation. The README notes that the project uses puppeteer-core rather than puppeteer and only installs Chromium if it does not already exist on the system, which the README estimates saves roughly 110 to 150 MB of disk space per user. That is a real saving, but it also means generation cannot run in a stripped container with no browser and no network to fetch one. A locked-down CI runner that forbids browser downloads will fail here in a way an image-resizing library would not. The second boundary is scope. This is a generation-time CLI, not a build plugin: it writes files and edits index.html and manifest.json when you invoke it, so a project that expects assets to appear automatically on every build needs a script step wired up by hand. Third, the README does not describe any handling for an index.html whose structure the tool does not recognize, and it does not document rollback. Treat the first run as a change to review, not a change to trust.

## How it differs from a Vite PWA plugin and from hand-exporting

The nearest alternative in a modern frontend project is a Vite PWA plugin that handles asset generation inside the build pipeline. The difference in approach is timing and mechanism: a build plugin generates assets as part of the bundler run and knows the hashed output filenames, while pwa-asset-generator runs as a separate command that renders through Chrome and then rewrites your source files. If your project already builds with Vite and you want assets regenerated on every build without a manual step, the plugin fits better. The other alternative is doing it by hand in a design tool, which is viable for a handful of icons and painful for the iOS splash screen matrix, where every device resolution needs its own image and its own media query. The README's own framing of that maintenance burden is the argument for the CLI. Note that the tool also emits maskable icons for Android by declaring them adaptively in the manifest, which is a detail easy to forget when exporting manually.

## Maintenance, licence and upgrade cost

The repository is not archived and the last push was on 2026-09-21, so it is being maintained. Releases v8.1.5, v8.1.6 and v8.1.7 landed between 2026-06-01 and 2026-09-21, and the project uses semantic-release, which means version numbers track commit conventions rather than a hand-written changelog. The licence is MIT, which permits commercial use and modification provided the copyright notice and permission notice are preserved; this is a factual description of the licence text, not legal advice, and you should read LICENSE in the repository if your situation is unusual. The upgrade cost to weigh is the Node.js floor: the README ties Node.js >= 22.12.0 to puppeteer-core v25, so a project or CI image on an older runtime cannot use the current release. The deprecated --scrape flag is a reminder that flags do get retired here, so pinning a version in CI rather than relying on npx fetching the latest is the lower-surprise option.

## Conclusion

Reach for pwa-asset-generator when an existing web app needs the full iOS splash screen matrix and manifest icon set without a design tool round trip. Skip it if your build already runs a Vite PWA plugin that emits assets at build time, or if you cannot install Chrome or Chromium on the machine doing the generation, since rendering depends on it. Before adopting, check the Node.js >= 22.12.0 requirement against your CI image, and run the CLI once against a copy of your index.html to confirm the injected link tags match the path layout you actually deploy.

## FAQ

### What is pwa-asset-generator used for?

It automates PWA asset generation and image declaration, producing icon and splash screen images plus favicons and mstile images, and updating manifest.json and index.html with the generated files according to Web App Manifest specs and Apple Human Interface guidelines.

### How do I install pwa-asset-generator?

Install it with npm install pwa-asset-generator, or run it once with npx pwa-asset-generator. It requires Node.js >= 22.12.0 and a compatible Chrome or Chromium browser, which the README says is installed automatically on first use when needed.

### Does pwa-asset-generator work offline?

The README states it works fully offline because the iOS and iPadOS device specs it needs are bundled with the package rather than fetched. The --scrape flag is described as a deprecated no-op.

### How does pwa-asset-generator generate the images?

It uses Puppeteer to drive Chrome, building a shell HTML page on the fly as an art board, centering the source on it, and taking screenshots at each target resolution. The source can be a local image or HTML file, or a remote image or HTML file.

## Sources

- [elegantapp/pwa-asset-generator on GitHub](https://github.com/elegantapp/pwa-asset-generator)
- [Issues](https://github.com/elegantapp/pwa-asset-generator/issues)
- [License: MIT](https://github.com/elegantapp/pwa-asset-generator/blob/master/LICENSE)
- [README](https://github.com/elegantapp/pwa-asset-generator/blob/master/README.md)
- [Releases](https://github.com/elegantapp/pwa-asset-generator/releases)

---

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