# Updates

> How HTML Clay checks for new versions, installs updates from the tray menu, and behaves on macOS, Windows, and Linux.

Source: https://htmlclay.com/docs/guide/updates/

HTML Clay checks for updates in the background, downloads new releases, and waits for you to install them from the [tray menu](https://htmlclay.com/docs/tray/). Open tabs and save permissions carry over across the restart.

## Install an update

While you are on the latest release, the top row of the tray menu shows the installed version, such as **HTML Clay v1.13.8**. When a new version has been downloaded and staged, that row changes to **Restart to Update (vX.Y.Z)**.

1. Click the HTML Clay icon in your menu bar or system tray.
2. Click **Restart to Update (vX.Y.Z)**.
3. If an [AI edit](https://htmlclay.com/docs/guide/ai-editing/) or a [document program](https://htmlclay.com/docs/programs/) is running, HTML Clay asks **Restart HTML Clay now to update to vX.Y.Z?** Click **Restart** to stop the running task and continue.

Before restarting, HTML Clay waits for 500 ms with no file writes, up to 5 seconds. While the restart is in progress, save requests receive HTTP `503` with `Retry-After: 2` and code `restarting`.

HTML Clay hands your open documents, save tokens, and permissions to the new process through `update-handoff.json` in the configuration folder, so your open browser tabs keep working and saving after the update finishes.

If the restart cannot complete right away, HTML Clay notifies you that it is still running the current version and keeps **Restart to Update** in the tray menu so you can try again. If the new version fails to start serving, HTML Clay rolls back to the previous binary and skips the failed version until a newer release is published.

## How updates work by platform

### macOS

On macOS, HTML Clay updates through Sparkle. Self-update requires HTML Clay to run from a writable `.app` bundle that includes an Ed25519 public key (`SUPublicEDKey`) and an `X.Y.Z` release version.

> [!NOTE]
> If macOS runs HTML Clay from a translocated path after download, self-update is disabled. Move `HTML Clay` to `Applications` so it can update itself.

If Sparkle does not quit the app within 40 seconds of clicking **Restart to Update**, HTML Clay reopens file writes and notifies you that the update will finish the next time you quit HTML Clay. Whenever Sparkle has prepared an update, quitting HTML Clay normally also installs it.

On macOS, you can also trigger an update from the terminal:

```bash
htmlclay update-now --version 1.13.8
```

The command asks the running HTML Clay process to update and prints `accepted`, `already X.Y.Z`, `refused <reason>`, `failed <reason>`, or `starting`, exiting with code `0` through `6`.

### Windows and Linux

On Windows and Linux, HTML Clay uses its built-in signed-feed updater:

- It checks `https://download.htmlclay.com/update/stable.json` 60 seconds after launch and every 6 hours after that.
- It only accepts a feed signed by a built-in Ed25519 key.
- It stores the highest version ever offered in `updates/seen.json` inside the configuration directory and refuses any older version.
- It downloads and stages the new binary beside the existing installation and never replaces the running binary until you click **Restart to Update (vX.Y.Z)**.

You can point the updater at an alternate signed feed by setting the `HTMLCLAY_UPDATE_FEED` environment variable.

## When self-update is off

Self-update is turned off when any of the following is true:

- You set `"updates": "off"` in [`config.json`](https://htmlclay.com/docs/configuration/).
- The folder or `.app` bundle where HTML Clay is installed is not writable.
- HTML Clay is running without a system tray (`-no-tray`).
- On macOS, the app is running outside an `.app` bundle, is translocated, has no `SUPublicEDKey`, or Sparkle fails to start.
- You are running a custom build without a release `X.Y.Z` version, update channel, or built-in signing key.

When self-update is off and the tray is active, HTML Clay checks `https://download.htmlclay.com/htmlclay-release-info.json` once at startup with a 5-second timeout. If a newer release is out, the tray menu shows **Update available: vX.Y.Z**, which opens the download page in your browser when clicked.
