Code Push
Code Push lets you push Dart code changes to deployed Flutter apps without going through app store review. Users get updates within hours instead of days.
How It Works
Code Push uses Approach B (Engine Swap):
- Developers use a standard Flutter SDK from flutter.dev.
- The
fcpCLI downloads a customgen_snapshotand engine library that include the code push runtime (C++ patch loader, updater, signature verification). - At build time,
fcp codepush releasecompiles the app with the custom engine and uploads the AOT snapshot as a baseline. - For patches,
fcp codepush patchcomputes a binary diff (BSDIFF50) between the baseline and the new snapshot, signs it, and uploads it. - At runtime, the app uses the
flutterplaza_code_pushpackage to check for updates, download patches, and apply them on next restart.
Prerequisites
- Flutter SDK 3.24.0 or later
fcpCLI installed:dart pub global activate flutter_compile- A FlutterPlaza account at codepush.flutterplaza.com
Quick Start
1. Authenticate
fcp codepush login --api-key YOUR_API_KEY
2. Download engine artifacts
# Auto-detects your Flutter version
fcp codepush setup
# Or specify version and platform
fcp codepush setup --flutter-version 3.24.0 --platform android-arm64
Artifacts are cached at ~/.flutter_compile/cache/codepush-engine/
and verified with SHA-256 checksums.
3. Register your app
cd my_flutter_app
fcp codepush init
This creates an app on the server and stores the app ID in ~/.flutter_compilerc.
4. Add the runtime package
flutter pub add flutterplaza_code_push
Add the update check to your app:
import 'package:flutterplaza_code_push/flutterplaza_code_push.dart';
Future<void> checkForUpdates() async {
final update = await CodePush.checkForUpdate();
if (update.isUpdateAvailable) {
await CodePush.downloadAndApply(
onProgress: (p) => print('${(p * 100).toInt()}%'),
);
// Patch takes effect on next restart.
}
}
5. Create a release
# Build and upload baseline
fcp codepush release --build --platform apk
This runs flutter build, swaps the engine library in the
build output, and uploads the AOT snapshot to the server.
6. Push a patch
# Make code changes, then:
fcp codepush patch --build --release-id RELEASE_ID --rollout 25
The CLI compiles the patched source, computes a binary diff against the
baseline, signs it with your RSA key, packages it as a .vmcode
file, and uploads it. Use --rollout for staged rollout (1-100%).
7. Roll back if needed
fcp codepush rollback --patch-id PATCH_ID
CLI Commands
| Command | Description |
|---|---|
fcp codepush setup |
Download code-push engine artifacts for your Flutter version |
fcp codepush init |
Register the current project as an app on the server |
fcp codepush login |
Authenticate with the code push server |
fcp codepush logout |
Clear stored credentials |
fcp codepush account |
Show subscription status and account info |
fcp codepush release |
Upload a baseline release (requires paid subscription) |
fcp codepush patch |
Upload a code push patch |
fcp codepush rollback |
Deactivate a patch so devices stop receiving it |
fcp codepush status |
Show releases and patches for an app |
Engine Artifacts
The fcp codepush setup command downloads pre-built engine
binaries from Google Cloud Storage. Each Flutter version has its own
set of artifacts:
| Platform | Artifacts |
|---|---|
| darwin-arm64 | gen_snapshot, libflutter_engine.dylib |
| darwin-x64 | gen_snapshot, libflutter_engine.dylib |
| linux-x64 | gen_snapshot, libflutter.so |
| windows-x64 | gen_snapshot.exe, flutter_engine.dll |
| android-arm64 | gen_snapshot, libflutter.so |
| ios-arm64 | gen_snapshot, Flutter.xcframework.tar.gz |
Artifacts are cached at
~/.flutter_compile/cache/codepush-engine/flutter-<version>/<platform>/
and verified via SHA-256 checksums.
Engine Swap
When you run fcp codepush release --build, the CLI:
- Runs
flutter build <platform> --releaseusing the standard SDK. - Replaces the engine library in the build output with the code-push-enabled version:
- Android:
libflutter.soinstripped_native_libs/ - iOS:
Flutter.frameworkfrom the xcframework archive - macOS:
FlutterMacOSinFrameworks/ - Linux:
libflutter_linux_gtk.soinbundle/lib/ - Windows:
flutter_windows.dllinrunner/Release/
- Android:
- Optionally re-runs
gen_snapshotwith--deterministicfor stable binary diffs.
Original files are backed up with a .original suffix.
Runtime API
The flutterplaza_code_push
package provides the runtime API. Key methods:
| Method | Description |
|---|---|
CodePush.checkForUpdate() | Check server for available patches |
CodePush.downloadAndApply() | Download and install the latest patch |
CodePush.installPatch(bytes) | Install a patch from raw bytes |
CodePush.rollback() | Remove the active patch |
CodePush.currentPatch | Get info about the active patch |
CodePush.isPatched | Check if a patch is active |
CodePush.releaseVersion | Get the base release version |
CodePush.patchCount | Number of patches stored on device |
CodePush.cleanupOldPatches() | Remove inactive patches |
CodePush.checkForUpdatePeriodically() | Periodic background update checks |
Security
- Patch signing: Patches are signed with RSA-SHA256 using the developer's private key. The engine verifies the signature before applying.
- Integrity verification: SHA-256 hashes are embedded in the
.vmcodeheader and checked on both the CLI and engine side. - Artifact verification: Engine artifacts downloaded via
fcp codepush setupare verified against SHA-256 checksums from the server. - TLS: All server communication uses HTTPS. Optional certificate pinning
is supported via
codepush_pinned_certin~/.flutter_compilerc. - App store compliance: Code push uses native AOT compilation, not interpretation. This complies with Apple's App Store Review Guidelines (3.3.2) and Google Play policies.
IDE Integration
Both the VS Code and IntelliJ / Android Studio extensions include a Code Push panel showing:
- Account status (email, subscription tier)
- App configuration
- Releases with version, platform, and creation date
- Patches with rollout percentage and active/inactive status
Actions like Login, Release, Patch, and Rollback are available directly from the IDE toolbar and context menus.
Pricing
Code push operations (release, patch) require a paid FlutterPlaza
subscription. See
codepush.flutterplaza.com/pricing
for tiers and limits. The fcp codepush account command shows your
current tier and subscription status.
Supported Flutter Versions
Run fcp codepush setup --list-versions to see all Flutter
versions with available code push engine artifacts.