Introduction

Understand what Otalan is, when to use it, and how the first safe OTA release flow works for Capacitor and Expo apps.

Otalan is an OTA release control plane for Capacitor and Expo apps. It lets a team publish compatible web asset updates to already-installed mobile apps without submitting a new native binary for every JavaScript, CSS, HTML, or static asset change.

The compatibility boundary is the important part. Otalan updates the web layer that is safe for the native binary already on the device. It does not change native iOS or Android code, native plugins, permissions, entitlements, store metadata, or the installed native binary.

The product model

Otalan has three jobs:

  • decide which bundle is compatible with an installed app
  • make the release path repeatable through the dashboard, CLI, and CI
  • give operators rollout, pause, resume, rollback, history, install-confirmation visibility, version spread by platform, and confirmation-rate analytics

At runtime, an installed app asks Otalan whether a compatible bundle is active. Otalan answers from the release state for that app target. The app runtime then downloads and applies the bundle according to the Capacitor or Expo integration you chose.

What you set up first

A working Otalan setup has two separate credentials:

  • OTA App Key: shipped in the supported mobile runtime so the app can check for updates.
  • OTA Publish Key: kept in the dashboard, CLI, local release tooling, or CI so releases can be published.

Do not swap them. App keys are for installed apps. Publish keys are for release automation.

The first setup has three practical steps:

  1. Wire the installed app runtime: use the Capacitor or Expo quick start for the app stack.
  2. Publish a baseline bundle: use the first-publish flow to create a known-good rollback target.
  3. Publish a small visible change: confirm the app receives it, then roll back once before widening rollout.

That sequence proves credentials, tuple matching, bundle validation, runtime delivery, install confirmation, and rollback before customers depend on the path.

The release target

Every release targets one exact compatibility tuple:

  • appId
  • platform
  • channel
  • runtimeVersion

That tuple is the release lane. iOS and Android are separate. production, beta, and internal are separate. Runtime version lines are separate.

Project
  App: com.company.app
    ios     / production / runtime 1.0.0 -> active bundle A
    ios     / beta       / runtime 1.0.0 -> active bundle B
    android / production / runtime 1.0.0 -> active bundle C
    ios     / production / runtime 2.0.0 -> active bundle D

Otalan activates at most one bundle for one exact tuple at a time. Rollouts and rollbacks stay inside that tuple, so one platform, channel, or runtime line does not accidentally receive a bundle meant for another.

Why the flow is safe

Otalan is designed to fail closed:

  • uploaded bundles are validated before activation
  • failed validation leaves the previous active bundle unchanged
  • runtime checks require an OTA App Key
  • releases match the exact tuple before delivery
  • rollout percentages limit exposure
  • pause and rollback are available without shipping a new native binary

The app team still owns app-specific safety: native compatibility, startup behavior, data migrations, third-party SDK behavior, and the decision to widen rollout.

What stays outside Otalan

Your app stack still owns:

  • native iOS and Android builds
  • App Store and Play Store submission
  • framework build or export commands
  • native plugins, permissions, entitlements, and binary code
  • client-side installation behavior for the runtime you chose
  • large media or content-heavy assets that should stay outside the OTA bundle and be referenced by URL

If a change needs a new native capability, ship a new store binary first. Use Otalan for web asset updates that remain compatible with that installed binary.

Current v1 scope

v1 focuses on a narrow, testable OTA release path:

  • Capacitor 7 and 8
  • Expo SDK 54, 55, and 56
  • iOS and Android release lanes
  • dashboard and CLI publishing
  • rollout, pause, resume, rollback, release history, and install confirmation

Older Expo or Capacitor versions, bare React Native projects, and custom update runtimes are outside the supported v1 scope.