# How installed PWAs pick up manifest changes

> Chrome re-checks an installed PWA's manifest about once a day, applies changes after all app windows close, and updates different fields on desktop and Android.

An installed PWA keeps a local copy of the manifest it was installed from. Chrome re-fetches the
live manifest on a schedule, compares it with that copy, and applies a changed manifest only
after the app's windows have all closed. Which fields trigger a re-check and which are applied
afterwards differ between desktop Chrome and Chrome on Android, and the desktop path cannot
update icons at all.

The behaviour documented here is Chrome's, as described by the Chrome team (web.dev, "How
Chrome handles updates to the web app manifest"); Edge 154 shares the desktop path as a Chromium browser. Apple
publishes no equivalent for Safari 27 Home Screen or Dock apps, and Firefox 157 installs no web
apps from the manifest, so this entry makes no claim about either.

## How it works

Every launch of the installed app, and every visit to the site in a browser tab, prompts
Chrome to check when it last compared the manifest. If that was before the browser last
started, or more than 24 hours ago, Chrome fetches the manifest again. A fetch that returns the
same values resets the timer and nothing else happens.

On desktop a changed value in any of `name`, `short_name`, `display`, `scope`, `shortcuts`,
`start_url`, `theme_color`, or `file_handlers` queues the new manifest; it is installed once
every window of the app is closed, and then every field is applied except `icons`, which
desktop Chrome does not update. Two rules sit on top: a changed `start_url` is applied only
when the manifest declares an `id`, because without one the old `start_url` is the app's
identity; and a `display` change from `browser` to `standalone` does not move users who chose
to open the app in a tab, since the user's window preference wins over the manifest.

On Android the same 24-hour check runs, but the trigger list is `name`, `short_name`,
`icons`, `background_color`, `display`, `orientation`, `scope`, `shortcuts`, `start_url`,
`theme_color`, and `share_target`, and applying the change means requesting a new WebAPK from
Google's minting server. Chrome waits until the app is closed, the device is charging, and it is
on Wi-Fi before asking; once the new WebAPK is installed every field, icons included, is
current. When the WebAPK server does not answer, Chrome backs off and checks as rarely as every 30 days (web.dev).

Renaming or moving the manifest file breaks the chain: Chrome re-fetches the URL it installed
from, and a 404 there means no update is ever found. Keep the manifest URL stable and change
its contents.

:::observed
Chrome 155 on Android 16 (English UI), `chrome://webapks`: each installed WebAPK is listed
with the rows **Manifest URL**, **Manifest Start URL**, **Display Mode**, **Last Update Check
Time**, **Last Update Completion Time**, and **Update Status**, plus a **Check Updates Manually**
link that forces the comparison without waiting for the 24-hour timer. On desktop Chrome 155 the
equivalent is `chrome://web-app-internals`, which dumps the registry, including each app's
manifest update state, as JSON.
:::

## Examples

The first two examples are manifest edits and what they do to installed users; the third is
how to see the result without waiting a day.

### Moving the start URL without creating a second app

A team moves its app from `/` to `/app/`. Because the manifest declares an `id`, Chrome treats
the edited manifest as the same app and applies the new `start_url` after the next check;
without `id`, the change would be ignored on desktop and the installed app would keep launching
`/`.

```json
{
  "id": "/",
  "name": "Ledger",
  "start_url": "/app/?source=installed",
  "scope": "/",
  "display": "standalone"
}
```

Add `id` before the move, in a release that changes nothing else: the `id` has to be present in
the installed copy for the later `start_url` change to be recognized.

### Changing the theme colour and knowing when users see it

`theme_color` is on both trigger lists, so a rebrand reaches installed users without a
reinstall. The timeline is the check cadence, not the deploy.

```json
{
  "name": "Ledger",
  "theme_color": "#0b5fff",
  "background_color": "#ffffff"
}
```

A desktop user who keeps the app open all day sees the old colour until they close the last
window after a check has found the change; an Android user also needs charging and Wi-Fi for
the WebAPK to be re-minted. Expect a day or two, and longer for devices that rarely charge on
Wi-Fi.

### Forcing an update check while testing

Chrome offers two developer paths around the 24-hour throttle: restart the browser (the
`about://restart` URL resets the timer) or launch it with
`--disable-manifest-update-throttle`. The script below is the companion check inside the app:
it compares the manifest the page can fetch with a version stamp baked into the installed
`start_url`, and tells the tester whether the installed copy is still the old one.

```js
async function installedManifestIsStale() {
  const installedVersion = new URL(location.href).searchParams.get('v'); // from start_url
  const live = await fetch('/manifest.webmanifest', { cache: 'no-store' }).then((r) => r.json());
  const liveVersion = new URL(live.start_url, location.origin).searchParams.get('v');
  if (!installedVersion || !liveVersion) return false; // no stamp: nothing to compare
  return installedVersion !== liveVersion;
}
```

The page cannot read the browser's stored copy; the stamp in `start_url` is the only part of
the installed manifest a page can observe, which is why `?v=` in `start_url` is a common
testing convention.

## See also

- [id manifest member](/reference/manifest/id/)
- [start_url manifest member](/reference/manifest/start-url/)
- [icons manifest member](/reference/manifest/icons/)
- [WebAPK: how Chrome installs PWAs on Android](/reference/installation/webapk/)
- [How Chrome handles updates to the web app manifest](https://web.dev/articles/manifest-updates) (web.dev)
- [Uniquely identifying PWAs with the web app manifest id property](https://developer.chrome.com/docs/capabilities/pwa-manifest-id) (developer.chrome.com)