Guides8 min read

Background vs foreground app updates: which UX should you pick?

Silent background updates on next launch, or a restart-to-update prompt? The tradeoffs of each OTA update UX and how to configure both with OtaKit launch and resume policies.

There are two good ways to apply an over-the-air update, and they feel completely different to users. A background update downloads silently and swaps in on the next launch — users never see it happen. A foreground update prompts the user to restart now to get the latest version. Neither is universally right; the choice depends on your app. This guide covers the tradeoffs and how to configure each in OtaKit.

Mental model: background updates optimize for invisibility; foreground updates optimize for immediacy. Pick per the update's urgency, not as a blanket setting.

The tradeoff

Background (silent)Foreground (prompt)
User sees anything?NoYes, a restart prompt
Applies whenNext cold startOn user accept, immediately
Best forRoutine fixes and featuresUrgent or must-have updates
InterruptionNoneInterrupts the current session
RiskUser on old version a bit longerPrompt fatigue if overused

Background updates (the sensible default)

OtaKit's default behavior downloads new bundles quietly in the background and activates them on the next cold start. Users just find themselves on the new version next time they open the app — no prompts, no friction. For the vast majority of releases (bug fixes, content, incremental features) this is exactly what you want.

It's controlled by update policies (launchPolicy, resumePolicy). The default combination stages in the background and applies on launch. See update strategies for the full matrix.

Foreground updates (when it matters now)

When an update shouldn't wait for the user to happen to relaunch, prompt them. Listen for the staged-update event and offer a restart:

import { OtaKit } from "@otakit/capacitor-updater";

OtaKit.addListener("updateStaged", () => {
  // show your own "Update ready — restart now?" UI, then:
  // await OtaKit.apply();  // reloads into the new bundle
});

Keep the prompt honest: a “restart to update” banner the user can dismiss, not a wall they can't pass — unless the update is genuinely mandatory, in which case see forced and mandatory updates.

A hybrid that works well

Many teams land on: background updates for everything by default, a gentle foreground prompt for updates flagged important, and --force-immediate reserved for true emergencies. That gives users a frictionless experience most of the time and a fast path when it counts.

Overusing prompts trains users to dismiss them. Default to silent, and spend the “interrupt budget” only on updates that truly warrant it.

Where to go next

See the events docs for listener details, and how OTA works for where activation fits in the delivery flow.

Related docs