Apple allows live updates of interpreted code and forbids downloading native code. Whether your app can ship over-the-air updates on iOS depends on one question: is your app logic interpreted at runtime, or compiled to machine code?
The rules behind this are explained in Does Apple allow live updates?. This page applies them to each stack. For the Android version, see which stacks can use live updates on Android.
The rule in one sentence
Section 3.3.1(B) of Apple’s Developer Program License Agreement allows downloaded interpreted code if it does not change the app’s primary purpose, does not create a store for other code, and does not bypass iOS security. Guideline 2.5.2 forbids everything else.
So: JavaScript and other interpreted code, yes. Swift, Objective-C, C++ and anything compiled ahead of time, no.
iOS live update compatibility by stack
| Stack | How the code runs on iOS | Live updates allowed? | Tooling |
|---|---|---|---|
| Capacitor | JavaScript, HTML, CSS in WKWebView (WebKit) | Yes | Capgo, Ionic Appflow |
| Ionic (on Capacitor) | Same as Capacitor | Yes | Capgo |
| Cordova | JavaScript in WKWebView | Yes | Capgo after migrating to Capacitor, legacy Cordova plugins |
| React Native / Expo | JavaScript bundle on Hermes or JavaScriptCore | Yes, JavaScript only | Expo Updates, self-hosted CodePush alternatives |
| NativeScript | JavaScript on an embedded engine | Yes, JavaScript only | Limited, mostly self-built |
| Flutter | Dart compiled AOT to machine code | Only through an interpreter | Shorebird (Dart interpreter for patches) |
| Native Swift / Objective-C | Machine code | No | Remote config and server-driven UI only |
| .NET MAUI / Xamarin | C# compiled AOT to machine code | No | Remote config only |
| Kotlin / Compose Multiplatform | Kotlin/Native compiled to machine code | No | Remote config only |
| Unity / Unreal | C# via IL2CPP or C++, compiled | No for code, yes for content | Asset bundles, scripted content (Lua) |
| Web wrapper (remote URL) | Website loaded in a WebView | Always live, but review risk | None needed, see note below |
Stack by stack
Capacitor, Ionic and Cordova: fully covered
Your entire UI and business logic is JavaScript running in WKWebView, Apple’s own WebKit engine. Apple’s rules were written with exactly this case in mind, and guideline 4.7 explicitly accepts HTML5 and JavaScript content not embedded in the binary.
A live update replaces the web bundle. The native shell, plugins and permissions stay the ones Apple reviewed. That is why Capgo is compliant by design: it cannot change native code even if you wanted it to. New native plugins or permissions still need an App Store release.
React Native and Expo: JavaScript yes, native modules no
React Native runs your JavaScript bundle on Hermes or JavaScriptCore. That bundle is interpreted code and can be updated over the air, which is what Expo Updates and Microsoft CodePush (retired in 2025) were built for. Teams leaving CodePush need a replacement.
Any change to native modules, the React Native version, or Info.plist needs a new binary.
Flutter: only through an interpreter
On iOS, Flutter compiles Dart ahead of time to ARM machine code. Downloading new machine code is forbidden, so stock Flutter cannot use live updates. Shorebird solves this by running patched Dart code in an interpreter, which brings it under the interpreted code exception. Read more in live updates for Flutter apps.
Native Swift, .NET MAUI, Kotlin Multiplatform: no code updates
These stacks produce machine code. There is no compliant way to download new logic. What you can do over the air is change data: remote config, feature flags for features already reviewed, server-driven UI, images and copy.
Unity and game engines: content yes, code no
Game code is compiled. Asset bundles (levels, art, balancing data) are content and can be downloaded. Embedded scripting languages like Lua are interpreted code and follow the same rules as JavaScript.
Remote URL wrappers: live, but risky for review
An app that only loads your website in a WebView is “updated” every time you deploy the site. The problem is not guideline 2.5.2 but guideline 4.2 (minimum functionality): Apple rejects apps that are just a website in a frame. Bundling the web app with Capacitor, adding native features, and using live updates avoids that.
What no stack can do on iOS
Whatever your framework, a live update cannot:
- Download native code, frameworks or dynamic libraries
- Add new permissions or entitlements
- Change the app into something the App Store listing does not describe
- Turn on features that were hidden from App Review
Where to go next
- The rules: Does Apple allow live updates?
- Android version of this page: Which stacks can use live updates on Android?
- Google Play rules: Does Google allow live updates?
- How it works: How live updates for Capacitor work
Ship live updates on iOS with Capgo
If you build with Capacitor, Ionic or Cordova, Capgo live updates send your web changes to iOS users in minutes, with channels, rollbacks, delta updates and end-to-end encryption.
bunx @capgo/cli@latest init
Follow the quickstart to send your first update.