PWA Favicons: Icons, Sizes & manifest.json Setup
Published November 24, 2025 · Updated June 9, 2026
A PWA needs three manifest icons: 192×192 any, 512×512 any, and a separate 512×512 maskable. Here's the exact site.webmanifest and how to link it.
A Progressive Web App needs exactly three icons in its web app manifest: a 192×192 PNG (purpose: any), a 512×512 PNG (purpose: any), and a separate 512×512 maskable PNG (purpose: maskable). You declare all three inside site.webmanifest and point the browser at that file with one <link rel="manifest"> tag in your <head>. That’s the whole requirement.
In one line: three manifest icons — 192 any, 512 any, and a padded 512 maskable — plus a <link rel="manifest">.
These manifest icons are not your browser-tab favicon. They only show up after someone installs the app — on the home screen, in the app drawer, on the splash screen. The tab, bookmarks, and search listings still use favicon.ico and favicon.svg from your <head>. You need both sets, and below is exactly how each fits together.
The complete site.webmanifest
Here’s an annotated manifest with the three required icons and the four fields that make a PWA installable. Save it as /site.webmanifest (or /manifest.json) at your site root:
{
"name": "Your Site Name",
"short_name": "Site",
"icons": [
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" },
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" },
{ "src": "/icon-512-maskable.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
],
"theme_color": "#2563eb",
"background_color": "#ffffff",
"display": "standalone"
}
What each field does:
name— the full app title shown on the install prompt and splash screen.short_name— the label under the home-screen icon, where space is tight. Keep it under ~12 characters.icons— the three entries above. Note they’re three separate files, not one icon with a combined purpose.theme_color— tints the Android status bar and the title bar of the installed window.background_color— the splash-screen background shown for the split second before your app paints.display—standalonehides the browser chrome so the app feels native. (fullscreen,minimal-ui, andbrowserare the other options.)
Link the manifest from your <head>
The manifest does nothing until the browser is told where it is. One tag handles that:
<link rel="manifest" href="/site.webmanifest">
The file name is up to you — site.webmanifest and manifest.json are both common. What matters is that your server sends it with the application/manifest+json MIME type, and that the src paths inside start with / (root-relative), not ./. (Full tag-by-tag breakdown →)
The maskable icon, explained properly
This is the part most setups get wrong, so it’s worth slowing down.
Android doesn’t display your icon as a plain square. The launcher masks it into whatever shape the device uses — a circle on stock Android, a squircle on Samsung, a rounded square elsewhere — and crops away everything outside that shape. Hand it a normal 512×512 with your logo filling the frame and the corners (and often the edges) get sliced off.
The fix is a dedicated maskable icon:
- It’s a 512×512 PNG with all the important artwork — logo, text, key shapes — inside a central circle 409×409 pixels wide. This is the “safe zone.”
- The roughly 50px ring around that safe zone is background only. The mask is allowed to eat into it; nothing important should live there.
- It carries
"purpose": "maskable"in the manifest.
Two rules to burn in:
- It needs its own padded artwork. You cannot reuse the plain
icon-512.png— that one fills the frame and will get clipped. The maskable version is zoomed out, with a solid background filling the corners. - Never write
"purpose": "any maskable"on a single file. A combined purpose means the same image is used both un-cropped (as theanyicon) and cropped (as the maskable icon), and one image can’t be correctly padded for both. You’d either waste space in tabs or get a clipped logo on the home screen. Ship two files with two purposes instead.
Why 192 and 512 specifically
The Web App Manifest spec doesn’t mandate a fixed list, but Chrome’s installability check effectively does, and these two are the ones that matter:
- 192×192 is the Android home-screen launcher size — the icon a user taps to open the installed app.
- 512×512 drives the install prompt and the splash screen, and it’s the source Chrome downscales for any in-between size it needs.
Provide both as any, add the 512 maskable, and you’ve satisfied every current PWA surface. There’s no need for 256×256, 384×384, or 1024×1024 — 512 is the largest size any browser requests, and bigger files just add weight.
Exporting a correctly padded maskable icon by hand — getting the 409px safe zone right, filling the corners, keeping the plain 192 and 512 crisp — is fiddly. FaviconBuilder takes one upload (an SVG, or a PNG/JPG at 512×512 or larger) and outputs all three PWA icons plus the ready-to-paste site.webmanifest and <head> HTML — free, no account, and the image never leaves your browser.
Manifest icons vs the browser-tab favicon
A common misread: “I’ve added 192 and 512 to my manifest, so I’m done with favicons.” You’re not. The two systems cover different surfaces and don’t overlap.
| Asset | Lives in | Appears when | Required for |
|---|---|---|---|
favicon.ico | <head> | Always (tab, bookmark, SERP) | Every site |
favicon.svg | <head> | Always (modern browsers) | Sharp tab icon, dark mode |
apple-touch-icon.png | <head> | Added to iOS home screen | iPhone/iPad |
| Manifest 192 / 512 / maskable | site.webmanifest | After PWA install (Android/desktop) | Installable PWA |
Manifest icons only render once the app is installed. Before that — and forever, for the 99% of visitors who never install — the tab and search listing pull from favicon.ico and favicon.svg. So a complete PWA still ships the full favicon set in its <head>:
<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="manifest" href="/site.webmanifest">
Use the same artwork across both sets so your brand stays consistent from the tab to the home screen. If your tab icon adapts to dark mode, your SVG can carry a prefers-color-scheme media query — manifest icons can’t, so keep them legible on both light and dark backgrounds. (Dark-mode favicons →) For the exact pixel dimensions behind every file here, see the favicon sizes guide.
Test the install before you ship
Once the manifest and icons are in place, verify it the way the browser will:
- Open Chrome DevTools → Application → Manifest. It lists your three icons and flags missing fields.
- Confirm Chrome offers an install option (the install icon in the address bar, or menu → “Install app”). PWA install requires HTTPS, so test on a real domain or
localhost. - Install on Android and check the launcher icon, the app-drawer icon, and the splash screen. Look specifically at whether the maskable icon’s logo survives the crop.
- Re-run after any icon swap — browsers cache manifests aggressively. Bumping the file name or appending a query string forces a refresh.
Summary
A PWA’s icon requirement is small and specific:
- Three manifest icons —
icon-192.png(any),icon-512.png(any), andicon-512-maskable.png(maskable). - The maskable icon is a separate, padded file with artwork inside the central 409×409 safe zone — never
"purpose": "any maskable"on one image. - Declare them in
site.webmanifestand link it with one<link rel="manifest">tag. - Manifest icons don’t replace the tab favicon — keep
favicon.ico,favicon.svg, andapple-touch-icon.pngin your<head>too.
Continue reading:
Frequently asked questions
What icons does a PWA need in the manifest?
Three: a 192×192 PNG (purpose: any), a 512×512 PNG (purpose: any), and a separate 512×512 maskable PNG (purpose: maskable) with its art inside a central 409×409 safe zone. Declare all three in site.webmanifest and link it with <link rel='manifest'>.
What is a maskable icon and why do I need a separate one?
A maskable icon is a 512×512 image padded so Android can crop it into a circle, squircle, or rounded square without clipping your logo. It needs its own artwork with all detail inside the central 409×409 safe zone — never reuse the plain 512 and never mark one file purpose: any maskable.
Why 192×192 and 512×512 specifically?
192×192 is the Android home-screen launcher size, and 512×512 is used for install prompts and splash screens. They're the two sizes the Web App Manifest spec and Chrome's installability check require; everything else is downscaled from the 512.
Do manifest icons replace favicon.ico and favicon.svg?
No. Manifest icons only appear after a user installs the PWA. The browser tab, bookmarks, and search results still use favicon.ico and favicon.svg linked in your <head>, so you need both sets.
Should the manifest file be called manifest.json or site.webmanifest?
Either works — the extension doesn't matter as long as the server sends the application/manifest+json MIME type. site.webmanifest is the common convention. Reference whichever name you use in <link rel='manifest' href='...'>.