Updates
How updates work across Happier apps, CLIs, installers, Docker images, and release assets.
Happier ships multiple apps + tools, and how updates work depends on how you installed each one.
This page is the “source of truth” for:
- which artifacts update automatically vs manually
- what commands to run for each install method
- how stable/preview/dev channels map to rolling release tags
- where “embedded UI” comes from in self-hosted deployments
Update channels
Most artifacts are published into channels:
stable(production)preview(pre-release / early access)dev(rolling nightly / newest publicdevbranch builds)
Only those three names are part of the public user contract. Internal release-ring ids are implementation details used by the pipeline/config layer and should not appear in user commands or public docs.
Under the hood, channels are implemented using rolling release tags (for example cli-stable, cli-preview, cli-dev, server-preview, ui-web-dev). Those tags are updated to point at the newest version in that channel.
Availability still depends on the artifact. For example, some assets expose all three public rings (stable, preview, dev), while others may currently expose only a subset.
Update matrix (everything we ship)
The table below covers all user-facing released assets and how updates work.
| Shipped asset | How you got it | Updates happen when… | Automatic? | How to update / control |
|---|---|---|---|---|
| Desktop app (Tauri, “Tori” / Happier desktop) | Installed app bundle (.app / installer) | The app checks a signed update feed and offers an in-app update | Checks automatically, install is user-triggered | Accept the in-app update prompt; stable/preview/dev is determined by which build you installed |
| Mobile app (iOS/Android) | App Store / Play Store | (1) JS/asset OTA updates may be fetched; (2) native updates come from the store | OTA can be automatic + user-applied; store updates are store-managed | In-app “Update available” banner applies OTA updates (reload). Native updates require installing the new store version |
| Web app (hosted) | You open the hosted web UI | New deployments go live; users get them on refresh | Yes (on refresh) | Refresh the page (hard refresh if your browser is caching aggressively) |
Self-hosted web UI bundle (happier-ui-web) | Embedded/served by your self-hosted server, Docker image, or runner | It changes when your server runtime updates (or when your runner downloads a newer UI bundle) | Depends on the host (see below) | Control updates via the host (Docker pull, happier relay host install, runner restart, or pin tags) |
Relay server Docker image (happierdev/relay-server) | docker run … happierdev/relay-server:<tag> | You pull a newer image tag and restart the container | No | docker pull … then restart/recreate the container; pin to an immutable tag or digest for strict control |
| UI embedded in relay-server Docker image | Part of the Docker image build | It updates with the Docker image | No | Same as the Docker image update (pull + restart) |
Relay server npm package (@happier-dev/relay-server) | npx … @happier-dev/relay-server happier-server … | The runner fetches the latest server runtime/UI bundle for the selected rolling tags on startup | Yes (on restart) | Restart the runner to pick up newest rolling tag; pin via --tag server-vX.Y.Z and --ui-tag ui-web-vX.Y.Z; disable UI via --without-ui or HAPPIER_SERVER_UI_DIR= |
| UI “embedded” in relay-server npm runner | Downloaded + cached by the runner (not shipped inside npm tarball) | The runner downloads the UI bundle when needed | Yes (on restart) | Same controls as the runner: --ui-tag …, --without-ui, or set HAPPIER_SERVER_UI_DIR to a fixed directory |
Managed Relay runtime (happier relay host …) | Install the Happier CLI, then run happier relay host install … | You rerun happier relay host install | No | happier relay host install (local or with --ssh user@host) |
CLI installer (https://happier.dev/install) | curl …install | bash / irm …install.ps1 | You rerun it (or use the CLI’s self-update for installer installs) | No | Re-run the installer, or run the lane-specific command (happier, hprev, or hdev) with self update |
| CLI installer payload | Installed under ~/.happier/cli{,-preview,-dev}/{versions,current,previous} with lane-specific shims in ~/.happier/bin and ~/.local/bin (or Windows equivalent) | You run happier self update, hprev self update, hdev self update, or rerun the installer | No (but it can show notices) | Installer lanes are stable (happier), preview (hprev), and dev (hdev). You can still target `--channel preview |
CLI npm package (@happier-dev/cli) | npm install -g @happier-dev/cli | You upgrade the npm package | No (but it can show notices) | npm install -g @happier-dev/cli@latest (or @next for preview) |
Stack npm package (@happier-dev/stack) | npm install -g @happier-dev/stack | You upgrade the npm package (or use hstack self update runtime install) | No (but it can show notices) | hstack self update (recommended in-stack) or npm install -g @happier-dev/stack@latest |
Integrity verification (binaries + bundles)
Self-host and relay runtime downloads are verified before install:
- SHA256: downloaded archive matches the published checksums file.
- minisign: the checksums file is verified with the embedded Happier minisign public key.
Desktop app (Tauri)
The desktop app uses Tauri’s updater plugin:
- it checks an update feed automatically
- it shows an in-app banner/prompt when an update is available
- installing the update downloads a signed bundle and restarts the app
Stable vs preview is determined by which desktop build you installed.
Dev builds use the same updater model, but point at the dev feed instead.
App (mobile + web)
Web app (hosted)
Hosted web UI updates are delivered by normal deploys: users get the latest on refresh.
Mobile app (iOS/Android)
There are two distinct update types:
- Native updates (new binary): delivered via the App Store / Play Store.
- OTA updates (JS/assets): when enabled, the app checks for an OTA update when it becomes active, fetches it, and shows an “Update available” banner to apply it (reload).
OTA updates are feature-gated by the server feature updates.ota (fail-closed if the server disables it).
CLI updates (binary vs npm)
Update notices (opt-out)
The CLI can print a periodic “update available” notice in TTY sessions and perform background checks.
The notice includes the command to update:
happier self update
Disable update checks + notices:
HAPPIER_CLI_UPDATE_CHECK=0
Tune frequency:
HAPPIER_CLI_UPDATE_CHECK_INTERVAL_MSHAPPIER_CLI_UPDATE_NOTIFY_INTERVAL_MS
hstack (stack tooling) has the same pattern:
- notice includes:
hstack self update - disable with:
HAPPIER_STACK_UPDATE_CHECK=0
If you installed the CLI via our installer (binary)
Check/update:
happier self check
happier self updatePreview channel:
happier self update --channel=previewDev channel:
hdev self updatePin to a specific version (or rolling tag like latest/next):
happier self update --to 0.1.2Rerunning the installer is also a valid update path:
curl -fsSL https://happier.dev/install | bashIf you installed the CLI via npm
Update with npm (the CLI will print the exact command when you run happier self update):
npm install -g @happier-dev/cli@latestPreview:
npm install -g @happier-dev/cli@nextInstallers & binaries (what’s automatic vs manual)
Installers and binary installs do not auto-update in the background.
What is automatic:
- Update notices for interactive CLI usage (TTY):
happierprints a notice and tells you to runhappier self updatehstackprints a notice and tells you to runhstack self update
What is manual:
- actually installing an update (running the update command or rerunning the installer)
CLI installer (install)
The installer supports a few “actions” that are useful for scripting:
# Check the installed binary + PATH shim
curl -fsSL https://happier.dev/install | bash -s -- --check
# Print the latest version available on the selected channel
curl -fsSL https://happier.dev/install | bash -s -- --version
# Update/reinstall to latest on the selected channel
curl -fsSL https://happier.dev/install | bashWindows (PowerShell) updates work the same way (rerun the installer).
Managed Relay runtime (happier relay host …)
Install or update your managed Relay runtime by running:
happier relay host install --mode systemRemote host (over SSH):
happier relay host install --ssh user@host --mode systemThen manage it with happier relay host status and happier relay host start|stop|restart.
Server / self-host updates
There are multiple supported self-host shapes. See also: Self-host runtime (installer vs runner).
Managed Relay runtime (happier relay host …)
Update/reinstall (install-or-update):
happier relay host install --mode systemThen restart if needed:
happier relay host restart --mode systemRelay server runner (@happier-dev/relay-server)
By default, the runner tracks rolling tags:
- server runtime:
server-stable/server-preview/server-dev - UI web bundle:
ui-web-stable/ui-web-preview/ui-web-dev
Updates are picked up on restart (the runner fetches tag metadata each time it starts).
Notes:
- Extracted artifacts are cached under your platform cache directory.
- If UI is enabled and
HAPPIER_SERVER_UI_DIRis not set, the runner downloads the UI bundle and setsHAPPIER_SERVER_UI_DIRautomatically.
Pinning example:
npx --yes --package @happier-dev/relay-server happier-server \
--tag server-v0.1.0 \
--ui-tag ui-web-v0.3.0Relay server Docker image
The Docker image updates only when you pull a newer tag and restart:
docker pull happierdev/relay-server:preview
docker compose up -d --force-recreateThe embedded UI updates together with the image.
Release artifacts
For artifact naming, supported targets, and manifest details, see Release artifacts.