Skip to content

v3.0.0

Choose a tag to compare

@github-actions github-actions released this 20 Jul 07:10
f173c6c

Expo Open OTA v3

v3 is the largest release since the project started. The server now hosts all your Expo apps behind a single deployment, with a web dashboard, progressive rollouts, A/B testing and an enterprise edition built on the same open-source core. It has been serving production traffic throughout the beta, to apps totaling more than a million monthly active users.

Coming from v2? Read the migration guide before upgrading, this release contains breaking changes.

Highlights

Multi-app support

One server hosts all your Expo apps. Each app gets its own branches, channels, API tokens and update history, and no Expo account is required anymore.

Control plane mode and the dashboard (#65, #87)

Plug in PostgreSQL and the server migrates itself into control plane mode: a web dashboard where your team signs in with individual accounts to manage apps, channels, tokens and rollouts. Stateless mode still works with nothing but a bucket and a few environment variables, and remains the simplest way to get started.

Progressive rollouts (#91)

Ship an update to 10% of devices, watch your metrics, then increase, finish or revert in one click from the dashboard, or from the CLI with npx eoas publish --branch production --rollout-percentage 10.

A/B testing

A channel can serve two branches at once, with devices split deterministically between them. Test two variants in production and promote the winner.

Enterprise edition (#88, #89, #90, #94)

For teams that need tighter control, the Enterprise edition adds single sign-on through any OIDC provider (Microsoft Entra ID, Okta, Google Workspace, Keycloak...), protected branches that only explicitly allowed tokens can publish to, and per-token IP allowlists. Everything else stays MIT-licensed and free.

Breaking changes

  • Apps now identify themselves with the expo-app-id request header instead of the server-side EXPO_APP_ID environment variable. Add it to updates.requestHeaders in your app config and rebuild.
  • The bucket layout now includes the app id. The re-path runs automatically on first v3 boot and needs delete permission on the bucket (s3:DeleteObject on S3, roles/storage.objectAdmin on GCS). The server answers 503 until it completes.
  • Publishing requires eoas v3: publish routes moved under /{appId}/.
  • Dashboard sign-in now takes ADMIN_EMAIL together with ADMIN_PASSWORD.
  • S3_KEY_PREFIX is renamed to BUCKET_KEY_PREFIX (the old name still works with a deprecation warning).
  • Prometheus metrics carry an appId label, and update_error_users_total now counts unique clients.

The migration guide walks through both paths, staying stateless or moving to control plane mode.

Also in this release

  • Readiness and liveness probes so orchestrators gracefully (#93)
  • PostgreSQL-backed stores with full test coverad to Go 1.25
  • The repository moved to [mercuretechnologies/eub.com/mercuretechnologies/expo-open-ota). Images
    and charts are published to both ghcr.io/mercuracy ghcr.io/axelmarciano` namespace, so
    existing deployments keep receiving updates with

Install or upgrade

  • Docker: `ghcr.io/mercuretechnologies/expo-open
  • Helm: helm install expo-open-ota oci://ghcr.its/expo-open-ota --version 3.0.0
  • CLI: npx eoas@3

Full changelog: https://github.com/mercureteompare/v2.3.22...v3.0.0