A 5-minute OTA update and rollback flow for Expo and Capacitor apps

cirtadev1 pts0 comments

Publish in 5 minutes | Documentation<br>Documentation

About

Quick Start

Build

Deploy

Integration

Tooling

Versions

Publish in 5 minutes<br>Create the first Otalan release path, publish a baseline bundle, verify one update, and prove rollback before widening rollout.

Use this page for the first publish path. It assumes the mobile app runtime is already wired with the matching OTA App Key, appId, channel, and runtimeVersion.<br>If the runtime is not wired yet, start with the Capacitor or Expo quick start first. This page is about publishing from the app repository.

code]:outline-0 [&>code]:border-dashed hover:[&>code]:border-primary hover:[&>code]:text-primary focus-visible:[&>code]:border-primary focus-visible:[&>code]:text-primary transition-colors [&>code]:transition-colors">Open the video on YouTube.<br>What this first publish proves<br>The first publish should be boring on purpose. It proves that:<br>ul]:my-0">the installed app can authenticate with an OTA App Key<br>ul]:my-0">the repository can publish with an OTA Publish Key<br>ul]:my-0">the app, platform, channel, and runtime version match<br>ul]:my-0">Otalan validates the bundle before activation<br>ul]:my-0">the app can receive a new compatible bundle<br>ul]:my-0">rollback restores a known-good bundle in the same tuple<br>Do this once before using Otalan for customer-facing changes.<br>One-time setup<br>ul]:my-0">Create or select an organization and project.<br>ul]:my-0">Register the mobile app ID used by the installed app.<br>ul]:my-0">Create an OTA App Key for the installed app runtime.<br>ul]:my-0">Create an OTA Publish Key for local publishing or CI.<br>ul]:my-0">Go to the app repository.<br>App keys belong in supported app runtime flows. Publish keys belong in release tooling.<br>The snippets below expect OTALAN_API_KEY to contain an OTA Publish Key such as otalan_ci_..., plus OTALAN_APP_ID, OTALAN_PLATFORM, OTALAN_CHANNEL, and OTALAN_RUNTIME_VERSION for the release tuple.<br>Publish the baseline<br>Publish a bundle that matches the current installed native app. This gives you a safe rollback target before you ship a new web change.<br>Capacitor<br># Install the Otalan CLI with Bun.<br>bun add -g @otalan/cli

# Authenticate with an OTA Publish Key.<br>otalan login --api-key "$OTALAN_API_KEY" --api-url "${OTALAN_API_URL:-https://api.otalan.com}"

# Link this repository to the Otalan app.<br>otalan init --app-id "$OTALAN_APP_ID"

# Run your app build command first, for example bun run build.<br>bun run build

# Then package the generated web assets for one platform/runtime line.<br>otalan bundle --target capacitor --platform "$OTALAN_PLATFORM" --runtime-version "$OTALAN_RUNTIME_VERSION"

# Upload, validate, and activate on the selected channel.<br>otalan publish --channel "$OTALAN_CHANNEL"

Use your real build command if it is not bun run build.<br>Expo<br># Install the Otalan CLI with Bun.<br>bun add -g @otalan/cli

# Authenticate with an OTA Publish Key.<br>otalan login --api-key "$OTALAN_API_KEY" --api-url "${OTALAN_API_URL:-https://api.otalan.com}"

# Link this repository to the Otalan app.<br>otalan init --app-id "$OTALAN_APP_ID"

# Export and package Expo OTA assets for one platform/runtime line.<br>otalan bundle --target expo --platform "$OTALAN_PLATFORM" --runtime-version "$OTALAN_RUNTIME_VERSION"

# Upload, validate, and activate on the selected channel.<br>otalan publish --channel "$OTALAN_CHANNEL"

For Expo, otalan bundle handles the export and produces both .otalan/bundle/bundle-.zip and .otalan/bundle/manifest.json.<br>Publish a visible change<br>After the baseline exists:<br>ul]:my-0">make a small visible JavaScript, CSS, HTML, or asset change<br>ul]:my-0">build or export the app assets<br>ul]:my-0">run otalan bundle<br>ul]:my-0">run otalan publish<br>ul]:my-0">trigger the app update check on a real device or simulator<br>ul]:my-0">confirm the visible change appears<br>Prove rollback<br>Before widening rollout:<br>ul]:my-0">roll back to the baseline bundle from the dashboard or CLI<br>ul]:my-0">trigger another app update check<br>ul]:my-0">confirm the app returns to the previous known-good state<br>Rollback stays inside the same appId, platform, channel, and runtimeVersion tuple. If the change needs native code, publish a new store binary instead of relying on OTA.<br>Dashboard publish<br>If you publish from the dashboard instead of otalan publish, still run otalan bundle first.<br>ul]:my-0">Capacitor: upload .otalan/bundle/bundle-.zip<br>ul]:my-0">Expo: upload .otalan/bundle/bundle-.zip and paste or drop .otalan/bundle/manifest.json<br>Keep the first release small<br>Keep the first release focused on proving the path. Avoid large media, broad rollout, and native behavior changes. Once baseline, update, and rollback all work, move the publish command into CI.

On this page

otalan publish bundle first runtime code

Related Articles