Self-hosted Expo Updates CDN for Ax108/radixel.
| Host | GitHub Pages |
| Layout | Versioned {platform}/{appVersion}/ |
| Protocol | Expo Updates v1 (manifest.json + bundles/ + assets/) |
| Not used | EAS Update |
Public base (after Pages is enabled):
https://ax108.github.io/radixel-ota/
android/<expo.version>/manifest.json
android/<expo.version>/bundles/…
android/<expo.version>/assets/…
ios/<expo.version>/manifest.json
ios/<expo.version>/bundles/…
ios/<expo.version>/assets/…
Example for app version 1.0.0:
https://ax108.github.io/radixel-ota/android/1.0.0/manifest.json
https://ax108.github.io/radixel-ota/ios/1.0.0/manifest.json
runtimeVersion inside each manifest must equal that folder’s <expo.version> (app.json → runtimeVersion.policy: "appVersion").
Old version folders stay on the CDN so older binaries keep working. Publish only replaces the folder for the version you export.
radixel-ota/
├── index.html ← tiny landing page
├── README.md ← this file
├── VERSIONING.md
├── .github/workflows/static.yml ← Pages deploy on `main`
├── android/
│ └── <appVersion>/ ← created by app publish script
│ ├── manifest.json
│ ├── bundles/
│ └── assets/
└── ios/
└── <appVersion>/
├── …
Do not commit placeholder manifests with fake bundle URLs — clients may try to download them. Empty platform folders are fine until the first real publish from the app.
- Repo Settings → Pages → Source: GitHub Actions.
- Push
main(this workflow’s trigger). - Wait for the Deploy static content to Pages Action.
- Confirm
https://ax108.github.io/radixel-ota/loads.
From Ax108/radixel:
- Confirm
expo.versionmatches the binary’sruntimeVersion. - Run
bun run ota:export:androidand/orbun run ota:export:ios(stages into this repo). - Commit + push this CDN repo’s
mainbranch so Pages deploys. - Cold-start a matching native build — it checks the baked
updates.urlfor that platform/version.