Live Updates
Ionic Appflow Live Updates push web bundle changes to installed Capacitor apps without going through the App Store / Play. Same trade-offs as React Natives OTA: JS-only changes deploy instantly; native changes need a binary release. Useful for fixing copy, swapping a config, or shipping a small feature without a 1-week store wait.
Set up Appflow Live Updates with a fast-rollback channel
EXAMPLE
# 1) Configure the Live Update plugin
# npm install @capacitor/live-updates
# npx cap sync
# capacitor.config.ts
# import { CapacitorConfig } from '@capacitor/cli';
# const config: CapacitorConfig = {
# appId: 'au.com.example.shop',
# appName: 'Shop',
# webDir: 'www',
# plugins: {
# LiveUpdates: {
# appId: '<APPFLOW_APP_ID>',
# channel: 'production', // or 'preview', 'qa'
# autoUpdateMethod: 'background',
# maxVersions: 2,
# }
# }
# };
# export default config;
# 2) Initialise the plugin on app start
# main.ts
import { LiveUpdates } from '@capacitor/live-updates';
import { Capacitor } from '@capacitor/core';
async function checkForUpdates() {
if (Capacitor.getPlatform() === 'web') return; // no-op in browser dev
const result = await LiveUpdates.sync();
if (result.activeApplicationPathChanged) {
// New bundle is downloaded; reload on next opportunity
await LiveUpdates.reload();
}
}
document.addEventListener('deviceready', checkForUpdates);
# 3) Build + deploy from Appflow
# Connect your git repo to Appflow.
# Appflow builds your web bundle on every push, hosts the result, and serves
# matching binaries via the configured channel.
# OR via CLI:
# ionic build --prod
# ionic deploy
# 4) Channels = environments
# - 'production' live users
# - 'qa' internal testers
# - 'preview' stakeholders + the dogfooding channel
# Promote a build by changing the channel mapping in Appflow Web UI.
# No code change, no rebuild.
# 5) Pin builds to binaries with Live Update 'binding'
# In Appflow, every binary build records the JS bundle version it shipped with.
# A JS bundle deploys ONLY to binaries whose native version is compatible
# (much like Expo's runtimeVersion). Bump the native version when you change
# native code.
# 6) Roll back instantly
# Appflow keeps the last N bundles per channel. Change the active build to
# the previous one; devices fetch it on next launch.
# Add UI for forced reload on rollback:
# await LiveUpdates.reload();
# 7) Per-user opt-in / rollouts
# Use a remote-config style flag in your app (or Appflow's percentage rollout)
# to gate the bundle download for a subset of users.
# 8) When NOT to live-update
# - You added a native plugin or modified Info.plist / AndroidManifest
# - You bumped Capacitor / a major native dependency
# - The change touches code that the store reviewed for the binary listing
# (e.g. moves an external link behind an in-app paywall — Apple guidelines)
# 9) Observability
# - Crashlytics on the bundle version (set a custom key 'js_version')
# - Alert on a sudden spike in JS errors after a deploy
# - Stage rollouts: 10% -> 25% -> 100% on the 'production' channel
# 10) Open-source alternative
# Capgo / capacitor-updater is a community OTA solution if you do not want
# Appflow. Same shape: a hosted bundle, a plugin in the app, a channel.
# 11) Decision tree
# - Web bundle / JS-only fix -> Live Update
# - Native plugin added -> Rebuild + store release
# - Major Capacitor / dependency bump -> Rebuild + store release
# - Marketing copy in JSON -> Live Update (or Remote Config)
Why it matters
Live Updates are JavaScript-only — every native plugin install, Info.plist edit, or AndroidManifest tweak requires a fresh binary. Encode the native version into the channel mapping so old binaries cannot accidentally fetch a bundle that calls a plugin they do not have, and "always-green" OTAs stay always green.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
# Ionic Live Updates ship JS-only fixes without store re-submission. ionic deploy build ionic deploy add --channel productionTry it Yourself »
Discussion
Loading…