I Built a Faster PWA Icon Generator in a Weekend


TL;DR

I built pwa-icons — a fast, interactive CLI that generates all the icons you need for iOS, Android, Windows 11, and favicons from a single image.

npx pwa-icons

118 icons in ~0.7 seconds. No Chromium. No Puppeteer. Just Sharp and good vibes.


The Problem

Every time I start a new PWA project, I dread the icon generation step.

You need:

  • 26 iOS icons (16px to 1024px)
  • 6 Android icons (48px to 512px)
  • 80+ Windows 11 icons (tiles, splash screens, variants)
  • Favicons (ICO, PNG, apple-touch-icon)

That’s 118 images from one logo.

I used to go to PWABuilder’s Image Generator, upload my image, wait, download the ZIP, extract it… every. single. time.

There’s also an npm package called pwa-asset-generator — but it uses Puppeteer and Chromium. That means:

  • ~200MB Chromium download on first run
  • Spawning a browser process for each generation
  • Slower than it needs to be

I wanted something fast, lightweight, and interactive.


The Solution: pwa-icons

I built pwa-icons over a weekend. Here’s what makes it different:

1. Fast — Really Fast

118 icons in ~0.7 seconds.

Image description

How? I use Sharp instead of Puppeteer. Sharp is built on libvips — a native C library that processes images in streaming chunks, not full-image buffers.

No browser. No overhead. Just raw image processing.

2. Beautiful Interactive CLI

I hate remembering flags. So I made pwa-icons fully interactive using @clack/prompts.

Just run:

npx pwa-icons

And it walks you through everything:

Image description

3. Smart Edge Detection

Most icon generators ask you to pick a background color. But what if your logo already has a background?

pwa-icons samples 1px from all four edges of your image and calculates the average color. This creates backgrounds that naturally extend your image.

4. Multiple Output Formats

PNG is great, but WebP is 8x smaller. AVIF is even smaller.

pwa-icons supports:

FormatTransparencyBest For
PNGMaximum compatibility
WebPModern browsers, ~8x smaller
AVIFNext-gen, smallest files
JPEGUniversal support

Image description

5. Optimization Levels

Choose how aggressively to compress:

  • None — Maximum quality
  • Light — Good balance (default)
  • Heavy — Smallest files

Image description

6. Favicon Generation

Generates everything you need:

favicon/
├── favicon.ico         # Multi-size (16, 32, 48)
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon-48x48.png
├── favicon-192x192.png
└── apple-touch-icon.png  # 180x180

Image description


How It Works

Installation

# Use directly (no install)
npx pwa-icons

# Or install globally
npm install -g pwa-icons
pwa-icons

Interactive Mode

Just run it and answer the prompts:

npx pwa-icons

Image description

CLI Mode

For CI/CD or scripting:

npx pwa-icons \
  -i logo.png \
  -o ./icons \
  -p ios,android,favicon \
  -f webp \
  --optimization light \
  -y

Output Structure

AppImages/
├── ios/
│   ├── 16.png ... 1024.png     # 26 icons
├── android/
│   └── android-launchericon-*.png  # 6 icons
├── windows11/
│   └── *.png                   # 80 icons
├── favicon/
│   └── favicon.ico, *.png      # 6 files
└── icons.json                  # Ready for manifest.json

The icons.json is ready to paste into your PWA manifest:

{
  "icons": [
    { "src": "ios/512.png", "sizes": "512x512" },
    { "src": "android/android-launchericon-192-192.png", "sizes": "192x192" },
    { "src": "favicon/favicon.ico", "sizes": "16x16 32x32 48x48" }
  ]
}

The Tech Stack

PackageWhy
Sharplibvips-powered image processing
@clack/promptsBeautiful terminal prompts
CommanderCLI argument parsing
p-limitConcurrency control (10 parallel ops)
png-to-icoMulti-size ICO generation

Built with Bun, works with Node.js 18+.


Test Coverage

I take testing seriously. The codebase has:

MetricCoverage
Functions100%
Lines99.33%
Tests92

Run bun test --coverage to verify.


Comparison with Alternatives

Featurepwa-iconspwa-asset-generator
EngineSharp (libvips)Puppeteer (Chromium)
Package size10 KB183 KB + Chromium
Speed~0.7s for 118 iconsSlower
Interactive CLI
Output formatsPNG, WebP, AVIF, JPEGPNG only
Optimization3 levelsNone
Edge detection
iOS splash screens
HTML/CSS input

If you need iOS device-specific splash screens or HTML/CSS rendering, check out pwa-asset-generator. It uses Puppeteer for a reason — browser rendering.

For everything else, pwa-icons is faster and lighter.


Try It Now

npx pwa-icons

Links:

Star it if you find it useful! ⭐


What’s Next?

I built this as part of my personal toolkit for freelance/consulting work. Some ideas for future versions:

  • Maskable icon support
  • iOS splash screen generation
  • Watch mode for development
  • Config file support (.pwaiconsrc)

Got feature requests? Open an issue!


Thanks for reading! If you found this useful, follow me for more developer tools and tips.