May 2025 · 8 min read
Expo EAS Alternative: Self-Host Your OTA Updates with Relay OTA
Expo EAS Updates charges per Monthly Active User. At scale this becomes a significant line item. Relay OTA is an open-source, self-hosted server that implements the same Expo Updates protocol — switch by changing one URL, keep every other line of code.
Why developers look for an Expo EAS alternative
Expo EAS Updates is well-built and tightly integrated with the Expo ecosystem. For small apps or teams already paying for EAS Build, the cost is easy to absorb. The problem appears at scale.
EAS Updates pricing is based on Monthly Active Users (MAU). As of 2025, the plans are:
| Plan | MAU limit | Monthly cost |
|---|---|---|
| Free | 1,000 MAU | $0 |
| Production | 10,000 MAU | $99 |
| Enterprise | 50,000 MAU | $299+ |
| Custom | Unlimited | Negotiated |
A mid-size app with 100,000 MAU will pay $500–1,000+/month purely for OTA update delivery. The underlying infrastructure cost for serving JavaScript bundles at that scale is a fraction of that — typically $5–30/month on commodity cloud storage and a small compute instance.
Beyond cost, some teams have data residency requirements, want to audit the full update pipeline, or simply prefer not to depend on a hosted service for a critical path in their app startup sequence.
How Expo Updates protocol works
When a React Native app with expo-updates starts, it sends a request to a configured update server URL. The request includes:
- App version (
runtimeVersion) - Platform (iOS or Android)
- Current update ID
- Release channel
The server responds with either "no update available" or a manifest pointing to a new JavaScript bundle stored at a given URL. The client downloads and applies it on next launch (or immediately, depending on config).
This protocol is open. Expo publishes the spec. Any server that implements it correctly works as a drop-in replacement for EAS Updates — including Relay OTA.
What Relay OTA is
Relay OTA is an open-source (MIT) OTA update server built specifically to implement the Expo Updates protocol. It is designed to be self-hosted on your own infrastructure.
Key properties:
- Implements Expo Updates protocol v0 and v1
- Stores bundles in Cloudflare R2 (S3-compatible object storage)
- Postgres database via Neon for release metadata
- Release channels (production, staging, preview)
- Per-platform targeting (iOS-only, Android-only, both)
- Rollback to any previous release via dashboard or CLI
- REST API for CI/CD integration
- Web dashboard for managing releases and teams
Relay OTA vs Expo EAS Updates
| Feature | Relay OTA | Expo EAS Updates |
|---|---|---|
| Pricing | Infrastructure only (~$5–30/mo) | Per-MAU ($0–$299+/mo) |
| Open source | Yes (MIT) | No |
| Self-hosted | Yes | No |
| Expo Updates protocol | Yes | Yes |
| Release channels | Yes | Yes |
| Rollback | Yes | Yes |
| Dashboard | Yes | Yes |
| CLI | Yes | Yes (eas update) |
| EAS Build integration | Via CI/CD | Native |
| Data residency control | Full | None |
How to switch from EAS Updates to Relay OTA
Relay OTA implements the same protocol, so the switch is a configuration change in your app — not a code rewrite.
Step 1: Deploy Relay OTA. The server runs on any Node.js host. The recommended setup uses Vercel (or Railway) for the API, Neon for Postgres, and Cloudflare R2 for bundle storage.
Step 2: In your app.json or app.config.js, update the updates URL:
// Before — EAS Updates
{
"expo": {
"updates": {
"url": "https://u.expo.dev/your-project-id"
}
}
}
// After — Relay OTA
{
"expo": {
"updates": {
"url": "https://your-relay-instance.com/api/manifest"
}
}
}Step 3: Push your first update via the Relay OTA CLI or REST API from your CI pipeline:
npx relay-ota publish \
--bundle ./dist \
--channel production \
--platform ios,androidThat is the full migration. Existing app binaries on user devices will start receiving updates from your Relay OTA instance on next launch.
Infrastructure cost breakdown
Running Relay OTA for an app with 100,000 MAU and daily updates:
| Service | Usage | Estimated cost |
|---|---|---|
| Neon (Postgres) | Release metadata, user accounts | $0–19/mo |
| Cloudflare R2 | Bundle storage + egress | $1–5/mo |
| Vercel / Railway | API compute | $0–20/mo |
| Upstash Redis | Manifest caching | $0–10/mo |
| Total | $1–54/mo |
Compare to EAS Updates at 100,000 MAU: $500–1,000+/month. The break-even point is typically around 5,000–10,000 MAU where the infra cost of self-hosting becomes less than EAS pricing.
When to stick with EAS Updates
Relay OTA is not the right choice for every team. Stick with EAS if:
- Your team has no one comfortable managing a self-hosted service
- You are under 10,000 MAU and cost is not a concern
- You rely heavily on EAS Build and want native EAS Updates integration
- You need Expo's support SLA for the update pipeline
For teams above 20,000 MAU, with backend engineers on staff, or with data residency requirements, self-hosting with Relay OTA pays for itself quickly.
Get started
Relay OTA is open source under the MIT License. The full deployment guide covers Neon, R2, and CI setup in detail.