codepush 0.2.8 copy "codepush: ^0.2.8" to clipboard
codepush: ^0.2.8 copied to clipboard

PlatformAndroid

Ship Dart fixes to installed Flutter apps without an app-store review. Signed patches, staged rollout, crash-safe rollback. Android needs no forked engine.

codepush #

Ship Dart fixes to installed Flutter apps without an app-store review.

Your app gets one file and one dependency line. Everything else — which bucket serves your patches, which key your releases trust, what has already been released — is resolved from the app id in that file.

# codepush.yaml
app_id: cp_7f3a9c2e5b1d4860
# pubspec.yaml
dependencies:
  codepush: ^0.1.0

That is the whole integration. No main.dart changes, no Android code, no pubspec asset entry.

What a patch can change #

Dart. Not native code, not plugins, not assets, not permissions. A Dart-level bug fix or a Dart-level feature; anything else still needs a store build.

Android and iOS work differently #

Android replaces libapp.so — all of your compiled Dart. The stock Flutter engine already knows how to boot from a different one, so Android needs no forked engine. A patch is a few megabytes.

iOS cannot load native code that was not signed into the bundle, so a patch there is Dart bytecode, run by the VM's interpreter, replacing function bodies in place. That needs a Flutter engine built with --dart-dynamic-modules, and the applier lives in a separate package:

dependencies:
  codepush: ^0.1.0
  codepush_ios: ^0.1.0   # only if you patch iOS

It is separate because it calls dart:_internal.applyCodePushPatch, which only the forked engine has — and a direct call to it fails to compile against a stock SDK. Keeping it out of this package is what lets an Android-only app, and every developer's debug build, use a stock Flutter.

Every patch is signed #

The signing key is generated on your machine and never leaves it. The server holds only the public half, and your app has that half compiled in.

So a compromised server can withhold a patch or serve an old one. It cannot forge one — the signature will not verify against the key baked into the binary. The same is true of a stolen API key.

A device checks, in this order: signature, then app id, then revocation, then engine, then release, then rollout, then the artifact hash. The signature is first because every check after it reads a field out of the manifest, and those are attacker-controlled until it passes.

If a patch breaks something #

A patch is only ever attempted. It stays live only if the app reaches a first frame; a crash before that quarantines it on the next launch, with no server involved.

You can also stop one everywhere:

codepush patches revoke 7 --reason "crash loop on Android 12"

Devices running it return to the shipped build on their next cold start. This is the one command that needs no signing key — requiring one to stop a bad patch would mean being unable to stop it from a machine that lacks it.

Showing a download #

Optional, and off by default. Add the strip if you want one:

Stack(children: [child, const CodePushStatusStrip(bottomOffset: 92)])

It appears while a patch downloads and disappears when it is done. It says nothing on success, deliberately: the patch takes effect the next time the app is opened, so "update ready" would be an interruption offering no action.

Getting started #

Install the CLI and register the app:

dart pub global activate codepush_cli
codepush login --token <key from your dashboard>
codepush init
codepush keys generate      # before your first release, always
codepush release android

See codepush_cli for the full workflow.

0
likes
140
points
--
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Ship Dart fixes to installed Flutter apps without an app-store review. Signed patches, staged rollout, crash-safe rollback. Android needs no forked engine.

Topics

#code-push #hot-update #ota #deployment

License

MIT (license)

Dependencies

codepush_protocol, crypto, dio, flutter, path_provider, shared_preferences

More

Packages that depend on codepush

Packages that implement codepush