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.

