Reference · generated from the build code
Every icon file
your platform
actually needs.
Favicon, PWA manifest, Tauri, Electron and the macOS menu bar — one table per target, with the exact filenames and frame sizes. Nothing here is transcribed by hand: the page is generated from iconflow/build.py, so it says what the tool ships and fails the build when the two disagree.
Web favicon
The modern set is smaller than most guides claim. An SVG covers every current browser at every size; the .ico exists only for legacy fallback, and it is one file, not three.
| File | Size | Why it exists |
|---|---|---|
favicon.svg | vector | Primary in every current browser. Scales to any size, one file. |
favicon.ico | 16 · 32 · 48 px frames | Legacy fallback. One container, three frames — not three files. |
apple-touch-icon.png | 180 × 180 px | iOS home screen. Flattened onto the background colour: iOS ignores alpha. |
icon-192.png | 192 × 192 px | Android home screen and the PWA install prompt. |
icon-512.png | 512 × 512 px | Splash screens and store listings. |
icon-512-maskable.png | 512 × 512 px | Adaptive icon. Artwork inset 10% per side and flattened, so no platform mask can remove part of the mark. |
site.webmanifest | JSON | Declares the three PNGs, theme colour and display mode. |
favicon-head.html | HTML | The paste-ready <head> block, generated with the assets. |
The <head> block
IconFlow writes this next to the assets as favicon-head.html, so the markup and the files are produced together and cannot disagree:
<!-- Paste into <head>. SVG is primary; .ico is the legacy fallback. -->
<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">
<meta name="theme-color" content="#0b0d12">
PWA manifest and maskable icons
An adaptive platform crops your icon to a shape it chooses. A square drawing that reaches the canvas edge loses its corners; one with transparency shows the mask through. Both problems are solved before export, by insetting the artwork and flattening it onto the background colour.
The generated site.webmanifest declares exactly three icons — the third carrying "purpose": "maskable":
{
"name": "My App",
"short_name": "My App",
"icons": [
{
"src": "/icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "/icon-512-maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
],
"theme_color": "#0b0d12",
"background_color": "#ffffff",
"display": "standalone",
"start_url": "/",
"scope": "/"
}
Safe zone. The maskable asset insets the artwork 10% on every side, leaving it at 80% of the canvas, then flattens it. Any platform mask — circle, squircle, rounded square — lands inside that margin.
Windows pinned-site tiles optional
Only produced with --windows-tiles. The artwork is centred on each canvas rather than stretched, which is why the wide tile takes a smaller scale than the squares.
| File | Size | Why it exists |
|---|---|---|
mstile-70x70.png | 70 × 70 px | Small pinned-site tile. |
mstile-144x144.png | 144 × 144 px | Legacy pinned-site tile. |
mstile-150x150.png | 150 × 150 px | Medium tile. |
mstile-310x310.png | 310 × 310 px | Large tile. |
mstile-310x150.png | 310 × 150 px | Wide tile — the one rectangle in the set. |
browserconfig.xml | XML | Points at the tiles and sets the tile colour. |
Tauri
Five PNGs plus the two desktop containers. The ICO frame order matches the Tauri CLI's own output, so the result drops into src-tauri/icons/ unchanged.
| File | Size | Why it exists |
|---|---|---|
icons/32x32.png | 32 × 32 px | PNG, written into src-tauri/icons/. |
icons/64x64.png | 64 × 64 px | PNG, written into src-tauri/icons/. |
icons/128x128.png | 128 × 128 px | PNG, written into src-tauri/icons/. |
icons/128x128@2x.png | 256 × 256 px | Retina pair for the 128 pixel tile. |
icons/icon.png | 512 × 512 px | The Tauri source image. |
icons/icon.ico | 32 · 16 · 24 · 48 · 64 · 256 px frames | Windows. Frame order matches the Tauri CLI's own output. |
icons/icon.icns | 16 · 32 · 64 · 128 · 256 · 512 · 1024 px frames | macOS bundle icon. |
Electron
electron-builder reads one source image per platform. The optional corner radius is applied to the raster frames only — your SVG master keeps its own geometry.
| File | Size | Why it exists |
|---|---|---|
build/icon.png | 1024 × 1024 px | Linux, and the electron-builder source image. |
build/icon.ico | 32 · 16 · 24 · 48 · 64 · 256 px frames | Windows installer and window icon. |
build/icon.icns | 16 · 32 · 64 · 128 · 256 · 512 · 1024 px frames | macOS app bundle. |
macOS menu bar and system tray
This is the target that fails most often, and it fails silently: a template image carries no colour at all. macOS reads its alpha channel and paints the shape itself, so a full-card app icon with an opaque background arrives as a solid black rectangle.
| File | Size | Why it exists |
|---|---|---|
tray/tray.png | 32 × 32 px | Colour tray icon at 2× density. |
tray/tray@16.png | 16 × 16 px | Colour tray icon at 1× density. |
tray/trayTemplate.png | 16 × 16 px | macOS template: pure black plus alpha. The system recolours it. |
tray/trayTemplate@2x.png | 32 × 32 px | Retina template pair. Required, not optional. |
tray/trayIcon.ts | TypeScript | Optional inline data-URL module (--tray-ts). |
Give the tray its own drawing. A menu bar mark needs real transparency around a sparse shape — usually a simplified version of the master, not the master itself. Pass it with --tray-svg. When you do not, IconFlow derives alpha from the mark's contrast, and if no semantic shape can be isolated it refuses the build rather than shipping a black square.
Chat emotes
An emote is judged smaller than its upload and on two backgrounds at once: Twitch draws it at 28 pixels, Discord and Slack at roughly 22 to 32, on white and on dark chat alike. Each size below is rendered natively from the SVG, not scaled down from the largest, and a file over its platform's upload limit fails the build instead of the upload form. all builds the app-icon targets; ask for emote by name.
| File | Size | Why it exists |
|---|---|---|
emote/28.png | 28 × 28 px | Twitch, as shown in chat. Uploaded with 56 and 112; at most 25 KB. |
emote/56.png | 56 × 56 px | Twitch, 2× density. At most 25 KB. |
emote/112.png | 112 × 112 px | Twitch, 4× density and the size Twitch reviews. At most 25 KB. |
emote/128.png | 128 × 128 px | Discord and Slack custom emoji. At most 128 KB (Slack's limit; Discord allows 256 KB). |
Why 16 pixels decides everything
Every size in the tables above is rendered from the same SVG, but only one of them is where icons actually fail. At 16 pixels a counter closes, a hairline vanishes, and two adjacent colours average into one. A design reviewed at 1024 pixels and exported downward can be unreadable in the browser tab it was made for — and the export step will not tell you.
IconFlow inverts the order. It renders native pixels through a pinned Chromium at every target size, shows you the result at 1:1, and ship fails closed unless automated checks are clean and all six human rubric scores are at least 4 out of 5.
Questions people ask
How many favicon files does a website actually need in 2026?
Six, plus a manifest. An SVG favicon for current browsers, a legacy favicon.ico holding the 16, 32 and 48 pixel frames, a 180 pixel apple-touch-icon.png, and 192, 512 and maskable 512 pixel PNGs declared in the web app manifest. Sets larger than this are almost always carrying files no current platform requests.
What sizes go inside favicon.ico?
16, 32 and 48 pixels. ICO is a container format, so those three frames live inside one file — you do not ship favicon-16.png and favicon-32.png alongside it.
What is the maskable icon safe zone?
Android and other adaptive-icon platforms crop your icon to a shape they choose, so anything near the edge can be cut. IconFlow insets the artwork 10% on each side — leaving it at 80% of the canvas — and flattens the result onto the background colour, so no mask can remove a meaningful part of the mark or reveal transparency.
Why is my macOS menu bar icon a black square?
A macOS template image carries no colour: the system reads only its alpha channel and paints the shape itself. Handing it a full-card app icon whose background is opaque therefore produces a solid black rectangle. The fix is a separate tray drawing with real transparency around a sparse mark. IconFlow detects the failure instead of shipping it: when a source covers too much of the canvas it derives alpha from the mark's own contrast, and refuses the build outright if no semantic shape can be isolated.
What icon sizes does Tauri need?
Five PNGs — 32, 64, 128, 256 (as 128x128@2x.png) and 512 — plus icon.ico for Windows and icon.icns for macOS. IconFlow writes the ICO frames in the same order the Tauri CLI does, so the output is a drop-in replacement.
What icon sizes does Electron need?
A 1024 pixel PNG for Linux and as the electron-builder source, an ICO for Windows and an ICNS for macOS. The container frames are the same desktop set used everywhere else: 16, 24, 32, 48, 64, 128, 256, 512 and 1024 pixels, selected per format.
Can I just resize a 1024 pixel PNG down to 16 pixels?
You can, and that is exactly where most icons fail. At 16 pixels a counter closes, a hairline disappears and two colours average into one. Downscaling produces the file but tells you nothing about whether the result is still readable. IconFlow renders every size from the SVG through a pinned Chromium and shows you the native pixels before anything ships.
Does IconFlow upload my artwork or call an image model?
No. There is no image model and no API key. You author the SVG, a pinned local Chromium renders it exactly as a browser would, and every file is written on your machine. The only network step is the one-time Chromium download.
Who owns the icons made with IconFlow?
You do. No attribution is required, there is no share-alike obligation on your output, and commercial use is unrestricted. Run iconflow license for the full answer.
One master. Every surface.
Stop exporting.
Start proving.
Everything on this page is one command away, and the first run is a genuine gated ship rather than a render.
pip install iconflow
iconflow setup
iconflow demo --out iconflow-demo