Favicons and app icons: sizes, ICO vs PNG vs SVG, and the web manifest

A favicon used to be one file. The same small mark now has to survive a 16-pixel browser tab in light and dark themes, a bookmarks list, a Windows shortcut, an iPhone home screen, an Android launcher that crops it into a circle, a splash screen and a Google search result — and each surface asks for a slightly different file. This guide gives you the shortest set that covers all of them — five files and two snippets — explains why a 1990s Windows container is still on the list, and shows how to make every size from one 1024-pixel master with the tools on this site. Every resize and ICO conversion below runs inside your browser tab, so an unreleased logo never leaves your machine.

The minimal set: five files and two snippets

Put these files at the site root — icon.svg, favicon.ico, apple-touch-icon.png, icon-192.png, icon-512.png — and reference them from the <head> of every page:

<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="manifest" href="/manifest.webmanifest">
<meta name="theme-color" content="#f6faf7">

Three details in those five lines are load-bearing. type="image/svg+xml" lets a browser that cannot render SVG icons skip that line instead of decoding the file as a bitmap. sizes="32x32" on the ICO matters because Chrome treats an ICO declared sizes="any" as scalable and can prefer it to the SVG; give the ICO its real size and Chrome and Firefox pick the vector. And every href starts with /: a relative href="favicon.ico" resolves to /blog/2026/favicon.ico on a nested page and quietly 404s.

The manifest carries the home-screen and install icons:

{
  "name": "Example App",
  "short_name": "Example",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#0b0f0d",
  "theme_color": "#0b0f0d",
  "icons": [
    { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" },
    { "src": "/icon-mask-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
  ]
}

The SVG is the one file that can react to the reader’s theme: a <style> block with a prefers-color-scheme media query is honoured by Chrome and Firefox when they draw the tab icon, so a dark mark can turn white on a dark tab strip:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  <style>
    .mark { fill: #14261d; }
    @media (prefers-color-scheme: dark) { .mark { fill: #ffffff; } }
  </style>
  <path class="mark" d="…"/>
</svg>

Safari is the holdout: at the time of writing it does not use SVG favicons and falls back to the ICO — one more reason the ICO stays. The monochrome rel="mask-icon" SVG it once wanted for pinned tabs has been optional since Safari 12 began showing ordinary favicons in tabs.

Why favicon.ico still exists

ICO is a container, not an image format. A 6-byte header — two zero bytes, the type 01 00 (icon; 02 00 is a cursor) and a 16-bit image count — is followed by a 16-byte directory entry per image and then the images. Each entry stores width and height in one byte apiece, where 0means 256, which is why 256×256 is the format’s hard ceiling. The image data is a Windows bitmap without its file header or, since Windows Vista, a complete PNG dropped in whole, so one file can hold 16, 32 and 48 px renderings and whoever opens it picks the closest.

Who still asks for it: a browser that finds no <link rel="icon"> requests /favicon.ico by name, so it belongs at the root even when linked; the shortcut Windows creates when you drag a tab to the desktop takes its icon from it; feed readers, link-preview bots and uptime monitors that never parse your HTML fetch it directly. The file command shows what is inside — for our own it reports MS Windows icon resource - 6 icons, 16x16 with PNG image data … 32x32 with PNG image data …, and xxd -l 6 favicon.ico reads 0000 0100 0600: type 1, six images.

You do not need six. Browsers draw the ICO at 16 or 32 pixels, Windows shows shortcut icons at 16, 32 and 48, and all of them scale a 32×32 entry acceptably, so a single-image ICO at 32×32 (48×48 if Windows matters more than file size) covers the fallback role — exactly the file the ICO converter on this site produces.

Every size, and who asks for it

SurfaceSizeFormatReferenced from
Browser tab, bookmarks, history, new-tab tilesAny — drawn at 16 and 32 pxSVG<link rel="icon" type="image/svg+xml">
Safari tabs, older browsers, bare /favicon.ico requests, Windows shortcuts32×32 (or 48×48)ICO, one image<link rel="icon" sizes="32x32"> plus the file at the root
Google search resultsAt least 48×48, squareAny of the aboveThe same rel="icon" links
iOS and iPadOS home screen180×180, opaquePNG<link rel="apple-touch-icon">
Android launcher, Chrome install prompt192×192PNGManifest icons
Splash screen, app switcher, desktop PWA window512×512PNGManifest icons
Android adaptive shapes (circle, squircle)512×512, full-bleed, 80% safe zonePNGManifest icons with "purpose": "maskable"

Chrome’s published install criteria list a 192 and a 512 icon; the check it enforces is a square icon of at least 144 px with a sizes attribute, and the 512 is what Android scales for the splash screen, so do not skip it.

Home screens: apple-touch-icon, maskable icons, splash and theme-color

iOS takes the apple-touch-icon and nothing else

Safari on iOS ignores manifest icons when a site is added to the home screen. It uses the apple-touch-icon link, and without one it requests /apple-touch-icon.png and /apple-touch-icon-precomposed.png from the root — those two 404s in your server log are iPhones looking for it. Supply a 180×180 PNG, the 3× rendering of a 60-point icon, and make it opaque: iOS composites transparent pixels onto black, and it rounds the corners itself, so pre-rounded corners get a second, mismatched radius. We point ours at the 192 px manifest icon — an RGB PNG with no alpha channel — and let iOS scale it; a dedicated 180 saves one resample.

Android, maskable icons and the 80% safe zone

When Chrome on Android installs a site it hands the launcher your icon, and the launcher applies the device’s shape: a circle on Pixel phones, a squircle or rounded square elsewhere. "purpose": "maskable" tells Chrome it may crop freely, so the artwork must be painted edge to edge and everything you care about must sit inside the safe zone: a centred circle whose radius is 40% of the icon width — 80% of its diameter, the middle 410 pixels of a 512 icon. Without one Chrome puts your any icon on a white disc with padding — the tell-tale look of a site that skipped this step.

The manifest above lists a separate maskable file because most logos are not painted edge to edge. One file declared "purpose": "any maskable" is allowed, but only full-bleed artwork that keeps its mark inside the safe zone can do both jobs — our 512 icon is a green gradient to the edges with a shield in the middle half, so we get away with one file; a wordmark that touches the edges cannot.

Splash screens and theme-color

Android builds the splash screen from background_color (fills the screen), the 512 icon (centred) and name (printed below); theme_color tints the status bar and, once installed, the title bar. The HTML <meta name="theme-color"> does the same for ordinary tabs — Chrome on Android colours the toolbar, Safari 15 and later the tab bar — and accepts a media attribute, so one tag per prefers-color-scheme value picks a colour per theme.

Making the whole set from one master

Start with two square masters exported from the tool the logo was drawn in: a 1024×1024 PNG with a transparent background (source for the favicon and the any icons) and a 1024×1024 PNG painted edge to edge (source for the apple-touch-icon and the maskable icon). Keep the original SVG too — that is icon.svg once you add the style block. No raster-to-vector step is involved anywhere: this site’s image to SVG page is explicit that it does not trace pixels into paths, and neither does any browser tool that claims to — a bitmap wrapped in SVG markup is still a bitmap, blurry at 32 px and enormous at 1024. The vector has to come from where the logo was drawn.

The PNG sizes

Drop the transparent master on Resize Image. The editor opens on its Resize tab with the current dimensions in the Width and Height fields; type 512into Width and, with the ratio lock closed, Height follows (the fields accept 1 px up to ten times the source’s shorter side). Press Save: the dialog repeats width and height, has a Name field — type icon-512— and a Format menu of png, jpeg, jpg and webp; a PNG master stays PNG unless you change it, and the download is a PNG at exactly 512×512. Repeat for 192, then from the edge-to-edge master for 512 (maskable) and 180. A 1024 master sits inside the editor’s 4096-pixel working limit, so nothing is downscaled unasked. Check each result with file icon-192.png, which should answer PNG image data, 192 x 192, 8-bit/color RGBA; PNG keeps the alpha channel, which our image formats guide explains JPEG never will.

If the master arrived as WebP, TIFF, PSD, HEIC or an old .ico, run it through the PNG converter first; formats the browser cannot decode are transcoded before the editor opens and transparency survives. Selecting several files offers Convert all to PNG (ZIP) or Edit each image, with the saves downloading together at the end. A file it cannot open stops with Could not read this image. The file may be corrupted or in a format this browser cannot decode.

The ICO

Drop the transparent master on the ICO converter, open the Resize tab, set 32×32 (or 48×48) and Save. The editor writes a PNG and ImageMagick, running in the page, converts it with convert save.png -resize 256x256> out.ico — the > means only images larger than 256 are shrunk — so the ICO comes out at exactly the pixels you set, as one image, transparency intact, named logo_output.ico for a logo.png source. Leave three things alone in the save dialog: keep the format on png (a JPEG intermediate has no alpha, so the transparent corners come back black), leave Max file size (KB, optional) empty and Compress image unticked — the first turns the output into a size-capped JPEG or WebP, the second into a compressed PNG, and both skip the ICO step. A failure reads Could not convert the edited image to ICO. Try saving as PNG or JPG instead.

Starting from the SVG instead of a PNG

You can drop the SVG itself on the PNG converter, but the editor rasterises it at the pixel size in its width and height attributes and the Resize fields stop at ten times that: width="40" height="40" opens as a 40-pixel bitmap that cannot be pushed past 400. Set both attributes to 1024 (leave viewBox alone) first, or export the PNG master from the vector app.

Testing what you shipped

Open the site in Chrome, press F12 and go to Application → Manifest. The panel lists and renders every icon it parsed and flags problems under Installability in plain words, for example Manifest does not contain a suitable icon - PNG, SVG or WebP format of at least 144px is required, the sizes attribute must be set, and the purpose attribute, if set, must include "any". or Downloaded icon was empty or corrupted.Lighthouse’s PWA category, which ran the same checks, was removed in Lighthouse 12 (Chrome 125), so the panel is now the place to look.

Check the headers with curl, because a wrong Content-Type is invisible in the browser — the icon simply never appears:

curl -sI https://example.com/icon.svg | grep -i content-type
# content-type: image/svg+xml
curl -sI https://example.com/manifest.webmanifest | grep -i content-type
# content-type: application/manifest+json
xxd -l 6 favicon.ico
# 00000000: 0000 0100 0100      a real ICO holding one image
# 00000000: 8950 4e47 0d0a      a PNG that was renamed to .ico

Object stores and CDNs are the usual culprits: a file uploaded to S3 without an explicit type is served as binary/octet-stream, and an older nginx mime.types may not know .webmanifest — add application/manifest+json webmanifest; to it. Chrome is lenient about the manifest type, but an SVG served as text/plain is never drawn.

Then defeat the cache. Browsers keep favicons in a store separate from the page cache that a hard reload does not touch, so a replaced file keeps showing the old artwork for days. Change the URL instead: append ?v=1 to every icon href and manifest src and bump the number whenever the artwork changes. That is what our own head does — /images/onmydevice-logo.svg?v=2, /images/icon-192.png?v=4 — with the filenames left stable. Finally test on real devices — an iPhone home screen, a Chrome-on-Android install, a tab dragged onto the Windows desktop — since each reads a different file from the set.

Common mistakes

  • A mark that vanishes on the tab strip. A dark glyph on a transparent background disappears on a dark theme, a white one on a light theme. Use the SVG media query above or put the mark on a filled rounded square — which is why so many favicons are coloured tiles.
  • Detail that cannot survive 16 pixels. A 16×16 icon has 256 pixels in total; nothing thinner than 64 px in the 1024 master — one sixteenth of its width, one pixel at 16 — will still read, and wordmarks fail beyond about three letters. Judge the 16 px output at 100%, not zoomed.
  • A PNG renamed to favicon.ico. Chrome and Firefox sniff the bytes and render it anyway, so it looks fine to you; Windows Explorer and stricter feed readers refuse it. file favicon.ico answering PNG image data is the diagnosis.
  • Missing attributes. No sizes on a manifest icon triggers the installability error quoted above; no type on the SVG link makes some browsers try to decode it as a bitmap.
  • A transparent or pre-rounded apple-touch-icon. Transparent pixels come out black on iOS, and rounded corners get rounded again by the system mask.
  • Any maskable on artwork that is not full-bleed. Android crops the corners and the padding becomes a visible ring; ship a separate maskable file.

Do this

  • Export two 1024×1024 masters — transparent and edge to edge — plus the original SVG.
  • Ship icon.svg, favicon.ico at 32×32, apple-touch-icon.png at 180, icon-192.png, icon-512.png and a maskable 512.
  • Use the head snippet and manifest above as written: root-relative paths, type on the SVG link, sizes="32x32" on the ICO.
  • Make the PNGs with Resize Image and the ICO with the ICO converter, format left on png and the size options left blank.
  • Verify with DevTools Application → Manifest, file and curl -I; append ?v= to every icon URL and bump it whenever the artwork changes.

Frequently asked questions

Do I still need a favicon.ico in 2026?

Yes, as the fallback. A browser with no <link rel="icon"> to go on requests /favicon.ico by name, Safari uses it instead of the SVG, and feed readers and link-preview bots that never parse your HTML fetch it directly. One 32×32 image inside it is enough; put it at the site root and link it with sizes="32x32".

What size should a favicon be?

Ship an SVG for browser tabs (it scales to any size), a 32×32 ICO as the fallback, a 180×180 PNG for the iOS home screen, and 192×192 and 512×512 PNGs in the web manifest for Android and the install prompt. Google recommends at least 48×48 for search results, which the SVG satisfies.

Why is my new favicon not showing after I replaced the file?

Browsers keep favicons in a separate cache that a hard refresh does not clear. Change the URL — append ?v=2 to the href and bump the number each time the artwork changes — and confirm the server sends image/svg+xml for the SVG. In Chrome, DevTools → Application → Manifest shows which icon files were actually loaded.

Can I make a multi-size ICO in the browser?

The ICO converter on this site writes one image per file, at whatever pixel size you set in the editor, capped at 256×256. That is all a modern favicon.ico needs. If you want 16, 32 and 48 in one file, build it from the PNGs with ImageMagick on your machine: magick favicon-16.png favicon-32.png favicon-48.png favicon.ico.

What is a maskable icon?

A manifest icon marked purpose: "maskable" that Android may crop into a circle, squircle or rounded square. It must be painted edge to edge, with everything important inside a centred circle whose diameter is 80% of the icon width. Without one, Chrome puts your icon on a white disc with padding.

Tools used in this guide

Every one of these runs in your browser — the files you work on never leave your device.

More images & photos guides