Update Strategies
OtaKit has one set of four policy values and three settings that decide when each one runs. The values — off, shadow, apply-staged, and immediate — describe what happens. launchPolicy, resumePolicy, and runtimePolicy describe when it happens. This guide walks through picking a combination; for the full field list see the Plugin API reference.
The four policy values
- off — do nothing automatically. Nothing is checked, staged, or applied.
- shadow — check for the latest update and stage it locally, but never apply it. The current session keeps running on the bundle it already has.
- apply-staged — apply a bundle if one is already staged. If nothing is staged, it falls back to shadow behavior for that check.
- immediate — check, stage, and apply the newest bundle right away when one is available. The reload can land mid-session — and since any release can be escalated with
--force-immediate, you rarely need this as the launch or resume default.
When each setting runs
launchPolicy— every normal cold start, once the app's runtime lane is already resolved. This is the one most apps tune, since it covers the vast majority of app opens. Default:apply-staged.resumePolicy— when the app returns to the foreground from the background, throttled bycheckInterval. Default:shadow.runtimePolicy— cold start specifically whenruntimeVersionchanges or resolves for the first time. In practice that's the app's first native install, or a native update where you bumpedruntimeVersionin the plugin config before that release. Default:immediate, so a fresh runtime lane catches up fast instead of waiting on a bundle staged under the old lane.
Recommended combinations
Hosted default — right for most apps
runtimePolicy: "immediate", launchPolicy: "apply-staged", resumePolicy: "shadow". Fast on first install, seamless between launches, and new bundles are ready to go as soon as a session restarts.
Update quietly, reload only with consent
Set launchPolicy and resumePolicy to shadow. Bundles stage in the background and nothing ever activates on its own — show a "restart to update" prompt from the updateStaged event and call apply() on accept (see Events & Listeners).
Full manual control
Turn all three policies off and drive the lifecycle yourself with check(), download(), and apply(). Use this when your app owns the entire update experience — see the Manual Flow section of the Plugin API reference.
Ship critical fixes instantly
This one isn't a config — it's per release. Mark it force immediate in the dashboard's release dialog or with otakit release --force-immediate: the flag is baked into the signed manifest, and devices on shadow or apply-staged escalate that one release to immediate — download, apply, and reload on their next check. No rebuild, no config change.
It's "immediate on the next check", not push, and the trial/rollback safety net still applies. Policies set to off never fetch a manifest, so they never see the flag. Because the reload can land mid-session, reserve it for broken releases — not routine rollouts.
Also see Channels & Runtime Version for how rollout audience and native compatibility lanes interact with these policies.