Releasing for Android
This page takes a Flutter app from its first signing setup to a build on Google
Play that can receive Shorebird patches. Steps 1 to 3 are the same one-time
setup any Flutter app needs. Step 4 builds the app bundle with
shorebird release android, which you then upload to Google Play.
Step 1: Configure application ID and permissions
Section titled “Step 1: Configure application ID and permissions”Open android/app/build.gradle.kts (Kotlin DSL, which flutter create
generates since Flutter 3.29) or android/app/build.gradle (Groovy, in older
projects) and check the applicationId, minSdk, and targetSdk:
versionCode and versionName come from the version in pubspec.yaml (see
App versioning and build numbers).
Shorebird reads the release version from the app bundle it builds. Keeping
Flutter’s values there keeps that version matching pubspec.yaml, and lets
--build-name and --build-number override it.
Ensure all runtime permissions requested in
android/app/src/main/AndroidManifest.xml comply with
Google Play Developer Policy.
Step 2: Create an upload keystore
Section titled “Step 2: Create an upload keystore”Google Play uses digital certificates to verify the author of an application.
Create a private signing key using the keytool utility:
Keep this keystore file secure and backed up. If you lose your keystore and do not use Google Play App Signing, you cannot update your application.
Step 3: Configure signing in Gradle
Section titled “Step 3: Configure signing in Gradle”shorebird release android runs Flutter’s Gradle build, so it signs the app
bundle with whatever release signing config your Gradle file sets up.
Create a file named android/key.properties to reference the keystore:
Load key.properties in your app’s Gradle file and use it for release builds:
To sign in CI, where the keystore isn’t on the machine, see Android code signing in the GitHub Actions guide.
Step 4: Create a Shorebird release
Section titled “Step 4: Create a Shorebird release”Google Play requires the
Android App Bundle (AAB)
format for new apps. shorebird release android builds a signed app bundle with
Shorebird’s Flutter, and uploads its compiled Dart code to Shorebird as the base
that later patches apply to:
When it finishes, it prints the path of the app bundle to upload, by default
build/app/outputs/bundle/release/app-release.aab. With a flavor, the path
includes the flavor name.
shorebird release takes the common flutter build options, such as
--flavor, --target, --build-name, --build-number and --dart-define,
and passes any other flutter build argument you put after a -- separator.
See Create a Release for those, and run
shorebird release --help for every option.
To obfuscate your Dart code, pass --obfuscate, and --split-debug-info with a
directory to keep the symbol files in:
Patches to an obfuscated release are obfuscated the same way automatically. See Code obfuscation and debug symbols.
Build an APK for testing or other stores
Section titled “Build an APK for testing or other stores”To get an APK as well as the app bundle, for distribution outside Google Play or
for QA, pass --artifact apk:
Shorebird doesn’t support Flutter’s --split-per-abi, and stops with:
To build an APK for one architecture instead, pass --target-platform:
--target-platform applies to the app bundle as well as the APK, so the bundle
from this release only runs on 64-bit ARM devices. Use it for APKs you
distribute yourself, and don’t upload that app bundle to Google Play.
See Build a smaller APK for one architecture and Distribute an APK outside Google Play.
Step 5: Upload to Google Play
Section titled “Step 5: Upload to Google Play”Upload the .aab that shorebird release android printed to the
Google Play Console through one of its
release tracks (see
Upload your app to the Play Console):
- Internal testing: Instant distribution to up to 100 designated testers without full store review delays.
- Closed testing (Alpha/Beta): Testing with larger defined groups or organizations.
- Open testing: Public pre-release track with store visibility.
- Production: General availability for all users. Supports staged rollouts (e.g., releasing to 10%, 20%, then 100% of users over several days to monitor crash rates).
You can release the same app bundle on several tracks, for example by promoting it from internal testing to production. Devices that install it from any track receive patches for that release.
Step 6: Ship fixes as patches
Section titled “Step 6: Ship fixes as patches”When you change Dart code in this version later, ship the change as a patch instead of a new store build:
A change to native code, a plugin with native code, assets such as images and
fonts, or the Flutter version needs a new store release: bump the version in
pubspec.yaml, then repeat steps 4 and 5. See
Create a Patch.
Building without Shorebird
Section titled “Building without Shorebird”For background: a Flutter app that doesn’t use Shorebird builds its store bundle
with flutter build appbundle, which writes the same
build/app/outputs/bundle/release/app-release.aab path. That build uses the
standard Flutter engine, which has no Shorebird updater, so it can never receive
a patch. Once your app uses Shorebird, use shorebird release android for every
build you upload to Google Play.