DEV Community

OnePassApps
OnePassApps

Posted on

The OnePassApps Web App Manifest: What a Phone Reads Before It Installs the App

I work on OnePassApps, and this is the install surface of our own site: the small JSON file a phone reads before it offers to put the app on a home screen. It is not in our sitemap, it is not behind an "Install" button, and it is not one of the nine apps - it is a document every page in the site points at from its <head>.

Here is what it actually contains, measured on 4 November 2026 against the live site.

Where the file lives

GET https://app.onepassapps.com/site.webmanifest answers HTTP 200 with Content-Type: application/manifest+json and 876 bytes of body. The response headers are ordinary for a static asset: Cache-Control: public, max-age=0, must-revalidate, an ETag, and x-content-type-options: nosniff.

The filename is not the usual one. /manifest.json and /manifest.webmanifest both answer 404; only /site.webmanifest serves the file. robots.txt allows it - that file is Allow: / with /api, /account, /sign-in and /sign-up disallowed, and this path is none of those. sitemap.xml does not list it, and should not: the sitemap lists the 16 pages a crawler should index, and this is not a page.

The whole file

{
  "id": "/",
  "name": "OnePassApps — Useful apps, one membership",
  "short_name": "OnePass",
  "description": "A growing collection of practical apps for everyday work, creativity, and life, with one account and one membership.",
  "start_url": "/",
  "scope": "/",
  "lang": "en-GB",
  "dir": "ltr",
  "display": "standalone",
  "display_override": [
    "standalone",
    "minimal-ui"
  ],
  "background_color": "#0B0D0F",
  "theme_color": "#0B0D0F",
  "categories": [
    "productivity",
    "utilities",
    "lifestyle"
  ],
  "icons": [
    { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" },
    { "src": "/icon-maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Field by field:

  • id, start_url, scope are all /. The installed app opens on the home page and owns the whole origin, so a shortcut into a studio is a route inside the app rather than a separate install.
  • name is the long title, short_name is OnePass - eleven characters, which is what a phone home screen shows under the icon.
  • lang is en-GB and dir is ltr. The same en-GB appears as inLanguage in the JSON-LD block on every page of the site.
  • display is standalone, and display_override repeats it with minimal-ui behind it. That is the newer form of the field: the browser picks the first entry it supports, and minimal-ui is the fallback when it supports none of them.
  • background_color and theme_color are the same value, #0B0D0F. One is the splash screen, one is the title bar, and on this site they are the same near-black. The identical value also appears in the <meta name="theme-color"> of all 16 pages.
  • categories are productivity, utilities and lifestyle - three of the standard web-app categories.

The three icons, measured from the bytes

The manifest names three icon files. I pulled all three and read their PNG headers and pixels rather than trusting the declared sizes.

  • /icon-192.png - 200, image/png, 6,478 bytes. The header says 192x192, 8-bit, colour type 6 (RGBA). 25.56% of its pixels are fully transparent, the top-left corner is (0, 0, 0, 0), and the centre pixel is (11, 13, 15, 255). It carries no purpose key, which means it defaults to any.
  • /icon-512.png - 200, image/png, 18,385 bytes. 512x512, again colour type 6 (RGBA), 26.0% of pixels fully transparent, same transparent corner and same (11, 13, 15, 255) centre. Same artwork as the 192 at a larger size: the mark sits in the middle of a transparent field.
  • /icon-maskable-512.png - 200, image/png, 8,750 bytes. 512x512, but colour type 2 - truecolour RGB with no alpha channel at all, every pixel opaque. 75.27% of the canvas is the teal (0, 229, 208). Along the middle row the teal runs from x=0 to x=82, the dark (11, 13, 15) from x=84 to x=427, and the teal again from x=429 to x=511.

That last file is not the transparent one with some padding added. Comparing /icon-512.png and /icon-maskable-512.png at the same coordinates gives a mean absolute difference of 38.17 per colour channel (maximum 437) across 4,096 sampled points. It is a separate drawing, and it has to be: a maskable icon is what the platform crops - to a circle, a squircle, a rounded square - so the artwork has to survive an unknown crop, which means full bleed to the edges with the mark inside the safe zone. The transparent-bordered icons cannot do that job, which is why both kinds are declared.

The iOS icon is not in the manifest

/apple-touch-icon.png - 200, image/png, 3,492 bytes - is 180x180, colour type 2, no alpha, fully opaque, teal in the corner and (11, 13, 15, 255) in the centre. It is the same artwork family as the maskable file: scaled to 512 and compared point for point, the mean difference is 5.55 per channel over the same 4,096 samples.

It is wired up separately from the manifest, with a <link rel="apple-touch-icon" href="/apple-touch-icon.png" /> and a <meta name="apple-mobile-web-app-title" content="OnePass" />. The title in that meta tag is the same word as short_name, so the label under the icon matches on both platforms. The manifest itself lists no 180px entry - that size is Apple-specific and the manifest is not, so it is linked from the page rather than declared in the file.

Every page points at it

All 16 URLs in the sitemap carry the same <link rel="manifest" href="/site.webmanifest" /> in their head, along with the theme-color meta, the apple-touch-icon, the apple-mobile-web-app-title and a viewport that includes viewport-fit=cover (the notch inset). The link is identical on every page, so the install metadata does not depend on which page you arrived on. The desktop tab icons are separate files again: /favicon.ico (200, image/vnd.microsoft.icon) and /favicon.svg (200, image/svg+xml), while /icon.svg is a 404.

What is missing: a service worker

This is the one real gap, and it is worth being exact about it.

There is no service worker. The single JavaScript bundle the site's pages load - /assets/index-CKM47TUG.js, 321,856 bytes - mentions serviceWorker four times, but not one of them is a registration: every occurrence sits in the cache-cleanup path, where navigator.serviceWorker is read so the app can unregister old workers and delete caches after a crash. There is no serviceWorker.register call in it. /sw.js, /service-worker.js and /worker.js all answer 404.

So the install metadata is complete and the offline story is not. The manifest tells a browser how the app should look and which icons to use; nothing is precached, so the installed app still needs the network to open. Whether a given browser then offers an install button depends on that browser's own criteria, and I did not test that - I read the files the site serves.

What is missing: everything else

The file is a plain, minimal manifest. There are no shortcuts, no share_target, no screenshots, no file_handlers, no related_applications, no launch_handler, and no prefer_related_applications. For a site whose whole point is nine separate apps, the absence of shortcuts is the most noticeable: an installed OnePassApps gets one entry on the home screen, not one per studio.

Limits of this measurement

One build, one browser, one day (4 November 2026), measured from outside the browser with plain HTTPS GETs. The icon figures come from parsing each PNG's IHDR chunk and decoding its pixels locally, not from a browser's rendering of them. No phone was involved, no install prompt was triggered, and no DevTools application panel was opened - the "no service worker" finding is about the JavaScript the site serves today, not about every browser that might cache it.

If you want the installable version of the thing itself, open the OnePassApps home page - the seven browser studios, NewsFlow and the movie tracker are all reachable from there - or read the app guides for what each one does and where it stops.

Top comments (0)