---
description: Learn which changes can ship as a Live Update and which require a native app store release — the most important rule for Capacitor and Cordova OTA updates.
title: Binary-Compatible Changes - Capawesome
image: https://capawesome.io/docs/assets/images/social/cloud/live-updates/binary-compatible-changes.png
---

[ Skip to content](#binary-compatible-changes) 

[ 🔐 Introducing the **Capacitor Vault** plugin — store secrets behind biometrics or a device passcode.](/blog/announcing-the-capacitor-vault-plugin/) 

* [  SDKs ](/docs/sdks/)
* [  Formbricks ](/docs/sdks/capacitor/formbricks/)
* [  Geocoder ](/docs/sdks/capacitor/geocoder/)
* [  Google Sign-In ](/docs/sdks/capacitor/google-sign-in/)
* [  Grafana Faro ](/docs/sdks/capacitor/grafana-faro/)
* [  libSQL ](/docs/sdks/capacitor/libsql/)
* [  Live Update ](/docs/sdks/capacitor/live-update/)
* [  Managed Configurations ](/docs/sdks/capacitor/managed-configurations/)
* [  Media Session ](/docs/sdks/capacitor/media-session/)
* [  ML Kit ](/docs/sdks/capacitor/mlkit/)
* [  Navigation Bar ](/docs/sdks/capacitor/navigation-bar/)
* [  NFC ](/docs/sdks/capacitor/nfc/)
* [  OAuth ](/docs/sdks/capacitor/oauth/)
* [  Pedometer ](/docs/sdks/capacitor/pedometer/)
* [  Photo Editor ](/docs/sdks/capacitor/photo-editor/)
* [  PostHog ](/docs/sdks/capacitor/posthog/)
* [  Printer ](/docs/sdks/capacitor/printer/)
* [  Purchases ](/docs/sdks/capacitor/purchases/)
* [  RealtimeKit ](/docs/sdks/capacitor/realtimekit/)
* [  Screen Orientation ](/docs/sdks/capacitor/screen-orientation/)
* [  Screenshot ](/docs/sdks/capacitor/screenshot/)
* [  Secure Preferences ](/docs/sdks/capacitor/secure-preferences/)
* [  Speech Recognition ](/docs/sdks/capacitor/speech-recognition/)
* [  Speech Synthesis ](/docs/sdks/capacitor/speech-synthesis/)
* [  Share Target ](/docs/sdks/capacitor/share-target/)
* [  Square Mobile Payments ](/docs/sdks/capacitor/square-mobile-payments/)
* [  SQLite ](/docs/sdks/capacitor/sqlite/)
* [  Superwall ](/docs/sdks/capacitor/superwall/)
* [  Torch ](/docs/sdks/capacitor/torch/)
* [  Vault ](/docs/sdks/capacitor/vault/)
* [  Wifi ](/docs/sdks/capacitor/wifi/)
* [  Zip ](/docs/sdks/capacitor/zip/)
* [  Cordova ](/docs/sdks/cordova/)
* [  Cloud ](/docs/cloud/)
* [  Integrations ](/docs/cloud/live-updates/integrations/)
* Concepts
* Reference
* [  Troubleshooting ](/docs/cloud/live-updates/troubleshooting/)
* [  FAQ ](/docs/cloud/live-updates/faq/)
* [  Native Builds ](/docs/cloud/native-builds/)
* [  Set Up Environments ](/docs/cloud/native-builds/environments/)
* [  Overwrite Native Configurations ](/docs/cloud/native-builds/native-configurations/)
* [  Auto-Increment Build Numbers ](/docs/cloud/native-builds/auto-incrementing-build-numbers/)
* [  Configure the Web Build Script ](/docs/cloud/native-builds/web-build-script/)
* [  Build from a Monorepo ](/docs/cloud/native-builds/monorepo/)
* [  Use pnpm or Yarn ](/docs/cloud/native-builds/package-managers/)
* [  Install Private npm Packages ](/docs/cloud/native-builds/npm-private-registry/)
* [  Override the Java Version ](/docs/cloud/native-builds/override-java-version/)
* [  Custom iOS Provisioning Profiles ](/docs/cloud/native-builds/custom-ios-provisioning-profiles/)
* [  Build without Git ](/docs/cloud/native-builds/build-without-git/)
* [  Access Git Behind a Firewall ](/docs/cloud/native-builds/firewall-access/)
* [  Integrations ](/docs/cloud/native-builds/integrations/)
* Reference
* [  Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [  FAQ ](/docs/cloud/native-builds/faq/)
* [  App Store Publishing ](/docs/cloud/app-store-publishing/)
* [  Submit a Build ](/docs/cloud/app-store-publishing/submit-a-build/)
* [  Submit Automatically After a Build ](/docs/cloud/app-store-publishing/submit-automatically/)
* [  Troubleshooting ](/docs/cloud/app-store-publishing/troubleshooting/)
* [  FAQ ](/docs/cloud/app-store-publishing/faq/)
* [  Automations ](/docs/cloud/automations/)
* [  Reference ](/docs/cloud/automations/reference/)
* [  Troubleshooting ](/docs/cloud/automations/troubleshooting/)
* [  FAQ ](/docs/cloud/automations/faq/)
* [  Assist ](/docs/cloud/assist/)
* [  CLI ](/docs/cloud/cli/)
* APIs and SDKs
* [  Webhooks ](/docs/cloud/webhooks/)
* [  Integrations ](/docs/cloud/integrations/)
* Account
* [  Organization ](/docs/cloud/organizations/)
* [  Two-Factor Enforcement ](/docs/cloud/organizations/two-factor-authentication/)
* [  Audit Logs ](/docs/cloud/organizations/audit-logs/)
* [  Billing ](/docs/cloud/organizations/billing/)
* [  License Keys ](/docs/cloud/license-keys/)
* [  AI ](/docs/ai/)
* [  Insiders ](/docs/insiders/)
* [  Billing & Plans ](/docs/insiders/billing-and-plans/)
* [  FAQ ](/docs/insiders/faq/)
* [  License ](https://capawesome.io/legal/eula/)
* [  Support ](/docs/support/)
* [  Contributing ](/docs/contributing/)
* Contributing code
* [  Code of Conduct ](/docs/contributing/code-of-conduct/)
* [  Questions ](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#creating-a-discussion)
* [  Blog ](/blog/)
* Categories

# Binary-Compatible Changes[¶](#binary-compatible-changes "Permanent link")

The single most important rule with Live Updates: **you can only update what already exists in the native binary.** Changes that don't touch native code are called _binary-compatible_ and can ship as a Live Update. Anything else needs a real app store release.

Understanding this rule comes down to understanding how your app is built, so let's start there.

## The two layers of your app[¶](#the-two-layers-of-your-app "Permanent link")

Every Capacitor and Cordova app is made up of two distinct layers:

![The web layer runs inside the native layer's WebView](/docs/assets/images/diagrams/live-update-layers-light.png#only-light) ![The web layer runs inside the native layer's WebView](/docs/assets/images/diagrams/live-update-layers-dark.png#only-dark) 

A Capacitor or Cordova app consists of a native layer and a web layer.

* **The native layer** is the compiled binary your users install from the App Store or Google Play. It contains the WebView, the native plugins, and the platform code that bridges JavaScript to native APIs. It can only be replaced by shipping a new build to the stores.
* **The web layer** is everything that runs inside that WebView — your HTML, CSS, JavaScript, and static assets. These files are _not_ compiled into the binary; they sit on disk and are loaded at runtime.

A Live Update replaces the **web layer only**. The native binary stays exactly as it was installed. That's what makes over-the-air updates possible — and it's also the source of the one rule you have to respect.

## What counts as binary-compatible[¶](#what-counts-as-binary-compatible "Permanent link")

A useful mental model: if your change only modifies files inside your web project — your `src/` and its build output — and doesn't add, remove, or upgrade a plugin or any native code or configuration, it's binary-compatible and can ship as a Live Update.

| Change                                         | Binary-compatible? | Where it ships |
| ---------------------------------------------- | ------------------ | -------------- |
| HTML, CSS, JavaScript                          | Yes                | Live Update    |
| Images, fonts, JSON, web-only assets           | Yes                | Live Update    |
| Web framework upgrade (Angular, React, Vue, …) | Yes                | Live Update    |
| Pure JavaScript dependency added or updated    | Yes                | Live Update    |
| Capacitor or Cordova plugin added or removed   | No                 | App store      |
| Capacitor or Cordova plugin major version bump | Usually no         | App store      |
| Native code (Java/Kotlin/Swift/Objective-C)    | No                 | App store      |
| AndroidManifest.xml, Info.plist, entitlements  | No                 | App store      |
| App icon, splash screen                        | No                 | App store      |

When in doubt, ask yourself a single question: _does this change require recompiling the native project?_ If the answer is yes, it has to go through the app store.

## Why it matters[¶](#why-it-matters "Permanent link")

Picture a user running version 5 of your native app. You publish a web bundle that calls a method on a plugin you only added in version 6\. Because the native layer on that device still belongs to version 5, the method doesn't exist — and when the bundle tries to call it, the app **crashes on launch**. The user can't open the app to receive a fix, so their only way out is deleting and reinstalling from the store.

This is by far the most common production failure with Live Updates, and it's entirely preventable.

## How to prevent it[¶](#how-to-prevent-it "Permanent link")

Bind each web bundle to the range of native versions it is compatible with, so a bundle only ever reaches devices that can run it. The recommended approach is **versioned channels** — one channel per native version, configured at build time — so a bundle uploaded for one native version is never delivered to a device running another.

See [Get Started](/docs/cloud/live-updates/setup/#make-updates-version-compatible) for the setup and [Manage Channels](/docs/cloud/live-updates/channels/) for the alternatives.

June 8, 2026 

 Back to top 