Core Concepts
Updato has three pieces that work together: a GitHub Action, a Cloudflare Worker, and a client library. Each has a single job.
The Three Pieces
GitHub Action
The Action runs in your CI pipeline. It:
- Runs your build script
- Copies the output to a dedicated CDN branch (default
cdn) - Writes a
manifest.jsonwith the version, file list, and module flags - Pushes the branch
The CDN branch holds every version under versions/<version>/ and a latest/ alias. The manifest is always at the root.
Cloudflare Worker
The Worker is a lightweight HTTP API with two endpoints:
GET /check?repo=owner/name&branch=cdn¤t=1.0.0– checks if a newer version existsGET /manifest?repo=owner/name&branch=cdn– returns the current manifest
It fetches and caches the manifest from GitHub’s raw CDN, then compares versions. In version mode it uses semantic version comparison. In commit mode it uses exact SHA matching.
The Worker also rate-limits per IP (60 requests per minute by default) and caches the manifest in KV.
Client Library
The client runs in the browser. It:
- Calls the Worker periodically to check for updates
- Downloads new files from GitHub’s raw content CDN
- Caches them in
localStorage - Hot-swaps scripts, stylesheets, and images without a reload
The library is CSP-safe, uses no inline styles, and tracks download metrics if enabled.
The Update Flow
Git Push triggers the GitHub Action
↓
cdn branch (manifest.json + assets)
↓
Cloudflare Worker (cached manifest)
↑ ↓
Client checks /check endpoint
↓
Downloads new files from raw.githubusercontent.com
↓
Hot-swaps in the DOM
- You push to your repo. The Action builds and deploys to the
cdnbranch. - A client calls
checkForUpdate(). The Worker reads the manifest, compares the client’s current version, and returns{ update: true, files: [...], latest: "1.0.1" }. - The client calls
downloadUpdate(), which fetches each file fromraw.githubusercontent.comand stores them inlocalStorage. - The client calls
applyUpdate(), which reads the cached files and hot-swaps them into the page.
Modes
Version mode
Compares versions semantically: 1.2.0 > 1.1.0. Good for tagged releases and stable apps. The version is read from package.json or set explicitly in the Action config.
Commit mode
Compares Git SHA hashes: any difference means an update. Good for canary builds and staging environments.
Storage
The client stores everything in localStorage:
| Key | Purpose |
|---|---|
updato_current |
Current version string |
updato_cache_<path> |
Cached file content per path |
updato:metrics |
Download metrics (if enabled) |
The clearCache() method removes all cache keys and the current version. The DownloadMetrics.clear() method resets metrics separately.
Next Steps
- Quick Start: Get everything running
- Client Library: Config, events, and API
- GitHub Action: Action inputs reference