Shorebird in Flutter: solved exercise with code push and OTA updates
Shorebird in Flutter: solved exercise with code push
Shorebird is the code push service for Flutter: it lets you ship Dart code updates directly to users without going through Google Play or App Store review. It was created by the original Flutter engineering team.
The concept is the same as React Native CodePush: you compile a patch of your Dart changes, upload it to Shorebird, and the app downloads and installs it the next time it opens.
Problem statement
Configure a Flutter project with Shorebird that:
- Initializes the integration with
shorebird init. - Checks for available updates on startup.
- Downloads and installs the patch in the background.
- Informs the user of the status with a minimal UI.
- Displays the current patch number on the client side.
Dependencies
Configuration
1. Install the Shorebird CLI:
Verify the installation with shorebird --version.
2. Create an account and authenticate:
3. Initialize Shorebird in the Flutter project:
This adds a shorebird.yaml with the project’s app_id.
4. Create the first release (production build uploaded to Shorebird):
Distribute this build on Google Play / App Store like any normal release.
5. When you have code changes to ship as a patch:
Users will receive the patch the next time they open the app.
Full solution
Key concepts
| Concept | Detail |
|---|---|
shorebird release | Full build distributed through the stores |
shorebird patch | Patch containing only Dart code changes |
ShorebirdUpdater | Flutter client to check and install patches |
updater.isAvailable | false in debug mode and simulators (release only) |
updater.checkForUpdate() | Queries the server for a newer patch |
updater.readCurrentPatch() | Number of the currently installed patch |
updater.update() | Downloads and installs the patch (applied on next restart) |
UpdateStatus.outdated | A patch is available |
UpdateStatus.upToDate | App is on the latest version |
Important limitations
- Dart only: Shorebird patches compiled Dart code. Changes to native code (Kotlin/Swift), assets, images, or pub.dev package dependencies cannot be shipped as a patch.
- Patch applied on restart:
updater.update()downloads the patch, but it activates the next time the user opens the app. - iOS: Shorebird complies with Apple’s policies; it only modifies Dart code, not native code.
- Free plan: includes a limited number of patches per month; check current pricing at shorebird.dev.
Common mistakes
isAvailablealways false during development: correct by design. Always test with a release build and internal distribution.- Changing assets and expecting them to arrive with the patch: does not work. Dart code only.
- Forgetting to run
shorebird releasebefore the firstshorebird patch: Shorebird needs a base release to calculate the patch diff against.
Practical application
Shorebird is especially valuable for apps with slow Apple review cycles, urgent bug fixes in production, or teams with frequent deployment pipelines. Combine it with feature flags to activate new functionality in a controlled way without republishing to the stores.
Recommended next exercises
- CI/CD with GitHub Actions in Flutter: solved exercise
- Flavors dev/prod in Flutter: solved exercise
- All Flutter exercises
Guided practice and next step
- More Flutter exercises
- C exercises to strengthen fundamentals
- Programming in C in 100 Solved Exercises
- View on Amazon (included in Kindle Unlimited)
FAQ
Does Shorebird violate Apple’s policies?
No. Shorebird only modifies compiled Dart code (AOT patches), not native code. Apple allows updating application logic as long as you don’t change the core functionality without review.
How long does it take for a patch to reach users?
Patches are downloaded the next time the app opens with a connection. They are applied on the following launch. The total time for most users is hours, not days.
Can I roll back a patch?
Yes. From the Shorebird dashboard you can promote a previous release as active, which causes apps to discard the faulty patch and revert to the previous state.