---
title: How Live Updates Work
description: Understand how Capacitor and Cordova Live Updates work under the hood — the web layer vs the native binary, bundle swapping, and App Store compliance.
---

# How Live Updates Work

A hybrid app has two layers. The **native layer** is the compiled binary installed from the App Store or Google Play — it contains the WebView, the native plugins, and the platform glue. The **web layer** is everything that runs inside that WebView: your HTML, CSS, JavaScript, and static assets.

A Live Update is an **over-the-air (OTA) update of the web layer only**. The native binary stays untouched. Instead of pushing a new build to the stores, you upload a new web bundle to Capawesome Cloud, and the Live Update SDK in your app downloads it, swaps it in, and reloads.

That constraint is also the feature: because nothing native changes, you don't need an app store review and your users don't have to take any action. It also means a bundle must stay compatible with the installed binary — see [Binary-Compatible Changes](binary-compatible-changes.md).

## Key terms

Live Updates revolve around a handful of entities in Capawesome Cloud. Here's what each one means:

- **App** — the top-level container in Capawesome Cloud that everything below belongs to. It maps to a single Capacitor or Cordova app.
- **Build** — a build of your app's web assets, run in the cloud or uploaded from your machine. Each build produces one artifact.
- **Artifact** — the output of a build. For a web build, that artifact *is* the bundle: a zip of your web assets, or a manifest pointing to your own server for [self-hosted](self-hosting.md) bundles.
- **Bundle** — the artifact of a web build (the bundle's ID is that build artifact's ID): the packaged web assets delivered over-the-air. It's the unit you deploy to a channel — one "Live Update". See [Bundles](bundles.md).
- **Channel** — a named stream of bundles that devices subscribe to, such as `production` or `staging`. Each device subscribes to exactly one channel. See [Channels](channels.md).
- **Deployment** — the link between a bundle and a channel. Deploying a bundle to a channel makes it the latest update for that channel's devices.
- **Rollout** — a deployment delivered gradually, to a growing percentage of the channel's devices, so you can limit exposure to a bad release. See [Rollouts](rollouts.md).
- **Device** — an installed instance of your app. Each device receives the latest [compatible](binary-compatible-changes.md) bundle from its channel. See [Devices](devices.md).

The publishing side fits together like this — a build produces an artifact, that artifact is the bundle, and a deployment puts it on a channel:

<figure markdown>
  ![Relationship between channels, deployments, builds, and artifacts](../../assets/images/diagrams/capawesome-cloud-bundles-light.png#only-light)
  ![Relationship between channels, deployments, builds, and artifacts](../../assets/images/diagrams/capawesome-cloud-bundles-dark.png#only-dark)
  <figcaption>How channels, deployments, builds, and artifacts relate in Capawesome Cloud</figcaption>
</figure>

On the device side, each device subscribes to one channel and pulls the latest bundle deployed there. The next section follows a single update all the way from your machine to that device.

## The update lifecycle

Every Live Update follows the same path, from publishing a bundle to applying it on a device. It happens in two stages.

**On your side** — you publish the update:

1. **Build** — produce your web assets, locally or in the cloud. See [Publish an update](publish.md).
2. **Deploy** — deploy the resulting bundle to a [channel](channels.md), making it the latest update for that channel's devices.

**On the device** — the [Live Update SDK](setup.md) takes over automatically:

1. **Check** — the SDK asks Capawesome Cloud whether a newer bundle is available for the device's channel.
2. **Download** — if there is, the bundle is downloaded and written to a local directory inside the app's sandbox.
3. **Stage** — the SDK records the downloaded bundle as the *next* bundle to load.
4. **Apply** — on the next app launch (or immediately, if you call `reload()`), the WebView loads the new bundle instead of the one shipped inside the binary.

By default, the WebView loads your web assets from a local path bundled inside the native app — the output of your build at the time you shipped the binary. Applying a Live Update simply points the WebView at the downloaded bundle's path instead. The path is persisted natively (in `SharedPreferences` on Android and `UserDefaults` on iOS), so the app keeps using the updated bundle across restarts until a newer one is applied.

When and how the *Apply* step happens is controlled by your [update strategy](update-strategies.md).

## Are Live Updates compliant with app store policies?

Yes. Both Apple and Google explicitly allow downloading and executing code inside a WebView, which is exactly what Live Updates do.

- **Apple** — the App Store Review Guidelines (section 3.3.2) allow downloading interpreted code as long as it doesn't change the primary purpose of the app, doesn't create a store for other code, and doesn't bypass the system's signing or sandbox. Web code running in a `WKWebView` meets all three conditions.
- **Google Play** — the Device and Network Abuse policy forbids apps from modifying or replacing themselves outside of Play, with an explicit exception for code interpreted in a runtime such as JavaScript in a WebView.

In short, app stores draw the line at *native* self-modification. Live Updates only touch the web layer, so they stay safely on the right side of that line.
