Guides8 min read

Staging environments with Capacitor update channels

One app ID, many environments. How to run dev, staging, and production for a Capacitor app using update channels — validate a bundle on staging, then promote the exact same build to production.

Web teams take dev/staging/production for granted. Mobile teams often don't have it, because each environment historically meant a separate build and a separate store listing. With update channels you get real environments from a single app ID — one installed binary that can follow dev, staging, or production update streams. Here's how to set that up with OtaKit.

The key idea: a channel is an environment. The same native binary points at whichever channel you tell it to, and each channel carries its own stream of bundles.

Define your channels

A typical setup is three channels:

  • development — bleeding edge, your team's devices.
  • staging — release candidates, QA and internal testers.
  • production — everyone.

Point devices at the right channel

The configured channel is the default; apps override it at runtime. Give your internal builds a way to switch — a hidden settings toggle, a build flag, or an environment check:

import { OtaKit } from '@otakit/capacitor-plugin';

// QA build follows staging; everyone else uses the configured default
if (isInternalBuild) {
  await OtaKit.setChannel({ channel: 'staging' });
}

See Channels & runtime version for the switching semantics — the override persists across launches until you clear it.

The promotion flow

This is where single-app-ID environments pay off. You release a candidate to staging, validate it on real devices, then promote the exact same bundle to production — no rebuild, so what QA approved is bit-for-bit what ships:

otakit upload --release staging
# QA signs off on the staging build, then:
otakit upload --release production

Don't rebuild between staging and production. Rebuilding reintroduces risk — a dependency could resolve differently, a timestamp could change a hash. Promote the artifact you tested. See channel promotion.

Where to go next

Combine this with testing OTA updates for the QA loop and npm scripts to make each environment a one-liner.

Related docs