I work on OnePassApps, so this is our own tool, and every number below was read out of the ZIP that the Icon Studio produced in a real browser on 7 November 2026 - off the disk, not off the panel, and not from memory.

A favicon pack is a small chore with a fixed shape: one source image in, a folder of near-duplicates out - a 16, a 32, a 48, an Apple touch icon, two Android sizes, an .ico, a web manifest, and the <head> tags to paste. The Icon Studio does that conversion in the browser tab. This post is what actually sits inside the ZIP, file by file.

What the panel says first

Two stages, and the empty state says what it will take:

  • 01 Source - "No SVG or PNG yet. Drop one on the stage or browse for it. SVG up to 5 MiB, PNG up to 24 MiB."
  • 02 Pack details - "Name the app for the manifest once an image is open. The pack covers 16 to 512 pixels."

The action button is Create favicon pack, and the result stage gives you a Download ZIP control.

The ZIP, on disk

The file written to disk is 13,279 bytes, and the panel calls it "13.0 KiB ZIP" with "9 files". There are indeed 9 entries in it:

Entry Bytes
android-chrome-192x192.png 1,593 bytes
android-chrome-512x512.png 7,167 bytes
apple-touch-icon.png 1,492 bytes
favicon-16x16.png 141 bytes
favicon-32x32.png 162 bytes
favicon-48x48.png 267 bytes
favicon.ico 624 bytes
html-snippet.txt 381 bytes
site.webmanifest 414 bytes

One detail you only see on disk: every entry is stored, not compressed. All nine have a compressed size equal to their uncompressed size. The nine files add up to 12,241 bytes of content, and the archive is 13,279 bytes - 1,038 bytes more, because ZIP still writes a local header, a central directory record and an end-of-directory record for every entry.

The six PNGs and their real pixel sizes

Reading the IHDR header of each PNG inside the archive gives the dimensions the file names promise:

File Pixels Bytes
favicon-16x16.png 16 x 16 141 bytes
favicon-32x32.png 32 x 32 162 bytes
favicon-48x48.png 48 x 48 267 bytes
apple-touch-icon.png 180 x 180 1,492 bytes
android-chrome-192x192.png 192 x 192 1,593 bytes
android-chrome-512x512.png 512 x 512 7,167 bytes

favicon.ico is a real multi-image icon

The ICO is 624 bytes and its header says type 1 with 3 images inside - it is not a single 16x16 renamed. The three images are the same three PNGs the pack also ships, byte for byte:

ICO image Matching PNG Compared
16x16 favicon-16x16.png byte for byte identical
32x32 favicon-32x32.png byte for byte identical
48x48 favicon-48x48.png byte for byte identical

The manifest names two of the six

site.webmanifest is 414 bytes of JSON. It lists the Android sizes only:

src sizes type
/android-chrome-192x192.png 192x192 image/png
/android-chrome-512x512.png 512x512 image/png

It also carries "name": "App", "short_name": "App", "theme_color": "#ffffff", "background_color": "#ffffff" and "display": "standalone". The 16, 32, 48 and Apple touch icons are not in it - a manifest is for installable surfaces, and those four are not one.

The app-name field really does reach the manifest

This one is worth a run of its own. The name field is the second input on the stage, it ships with the value App, and the manifest comes out carrying "name": "App". To check that the field is actually wired to the file and not just echoed back, I typed a different name into it, built the pack again, and read the second ZIP off the disk: the manifest then carried "name": "OnePassApps" and "short_name": "OnePassApps", and the archive grew by exactly 16 bytes - the two longer name strings, once each.

The snippet is the markup, verbatim

html-snippet.txt is 381 bytes: 6 lines, 6 line feeds and 0 carriage returns - Unix endings, one tag per line, a newline after each. The tags are the same six the panel prints above its Copy snippet button:

<link rel="icon" href="/favicon.ico" sizes="any"> <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"> <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="48x48" href="/favicon-48x48.png"> <link rel="apple-touch-icon" href="/apple-touch-icon.png"> <link rel="manifest" href="/site.webmanifest"> 

Nothing left the tab

With the network trace on for the whole session - open the page, drop the image in, create the pack, download the ZIP, then do it all again - the browser made 172 requests, every one of them a GET, and not one carried a request body. The source image's file name appeared in no request URL. The only hosts reached were api.onepassapps.com, app.onepassapps.com, clerk.onepassapps.com, static.cloudflareinsights.com - our own site, our API host, the sign-in script host and the analytics beacon.

Where it does not fit

A browser tab is a good home for icon-sized art and a bad one for anything huge. The pack is still handed to you as a ZIP, so you unzip it and copy the files into your project - it replaces the resizing and the markup, not the deployment. And the size set is fixed at 16 to 512 pixels; a bespoke size still needs an image editor.

What I did not test: one build, one browser, one signed-out session, 7 November 2026. I did not open the exported files in an image editor or in a browser, I did not test an SVG source, I did not check how the pack behaves in a project that already has its own icons, and I did not test an app name with a character that needs escaping in JSON.

The app guides spell out what each browser tool does and where the boundary is.

I work on OnePassApps, so this is our own build and our own output, measured today rather than described from memory.