Feature SDKs (Pro)
shorebird_sdk Pro
- Tier
- Proversion 1.1.8
- Command
archipelago generate shorebird_sdk- Generates
features/shorebird/shorebird_updater_apifeatures/shorebird/shorebird_updater_impl
- Depends on
- shared_identifiersgenerate these first
OTA code-push SDK wrapping
shorebird_code_push. Generatesshorebird_updater_api(contract + sealed result models) andshorebird_updater_impl(ShorebirdUpdaterwrapper with injectable DI). Optionally generates CI patch docs. A passive SDK — it owns no routes or screens; the host app decides when to check and how to prompt.
Variables
| Variable | Type | Default | Description |
|---|---|---|---|
shorebirdAppId | string | "" | Your Shorebird app_id from shorebird init or the dashboard. Leave blank to fill in shorebird.yaml manually. |
includeCiPatches | boolean | true | Generate docs/shorebird-ci-patches.md with sample diffs for CI integration. |
Install
Interactive
archipelago generate shorebird_sdkNon-interactive (CI)
archipelago generate shorebird_sdk --config my_config.jsonpre_gen prints a reminder to run shorebird init in the app directory after generation; post_gen prints the same next-step list on success.
Generated Structure
apps/
└── template_app/
└── shorebird.yaml # app_id: {{shorebirdAppId}} or REPLACE_ME
features/
└── shorebird/
├── shorebird_updater_api/ # Contract + sealed result models (no plugin deps)
│ └── lib/src/
│ ├── shorebird_updater_sdk.dart
│ └── models/ # ShorebirdConfig, PromptCopy, UpdateStrategy, UpdateCheckResult, UpdateApplyResult
└── shorebird_updater_impl/ # shorebird_code_push wrapper + injectable DI
└── lib/src/
├── shorebird_updater_sdk_impl.dart
└── di/
docs/
└── shorebird-ci-patches.md # only if includeCiPatches = truePublic API
final updater = getIt<ShorebirdUpdaterSDK>();
if (!updater.isAvailable) return; // debug build, `flutter run`, or web
// 1. Silent (fire-and-forget) — recommended for most apps.
await updater.updateNow(UpdateStrategy.silent);
// 2. Prompt UX — check first, then download only on user confirmation.
final result = await updater.checkForUpdate();
if (result is UpdateAvailable) {
final confirmed = await showMyUpdateDialog(context, result.patchNumber);
if (confirmed) await updater.downloadUpdate();
}checkForUpdate() returns a sealed UpdateCheckResult: NoUpdate, UpdateAvailable(patchNumber), UpdateDownloaded, or UpdateCheckError(reason) — it never throws. downloadUpdate() returns a sealed UpdateApplyResult: DeferredUntilRelaunch or UpdateFailed(reason). Patches take effect on the next cold start, never immediately — the host app must call Restart.restartApp() (from the restart_app package) itself if it wants to apply a downloaded patch right away. UpdateStrategy.prompt and .force are treated identically by updateNow — both just run checkForUpdate and return a sentinel; true prompt/force UI is the caller's responsibility (the force strategy exists only for API symmetry/documentation, per the source comment on UpdateStrategy).
getCurrentPatchNumber() returns the currently-installed patch number, or null if none has been applied yet.
DI & Wiring
ShorebirdUpdaterImplPackageModule is registered as an external module in the app's injector.dart. ShorebirdUpdaterSDKImpl is an eager @Singleton(as: ShorebirdUpdaterSDK), so it joins FeatureSDKRegistry during initializeInjector(). When ShorebirdConfig.checkOnLaunch is true (the default), initialize() fires a background checkForUpdate() → downloadUpdate() chain, unawaited, so it never blocks launch.
Override the default ShorebirdUpdater/ShorebirdConfig bindings in your own @module:
@module
abstract class MyAppShorebirdModule {
@lazySingleton
ShorebirdConfig get shorebirdConfig => const ShorebirdConfig(
defaultStrategy: UpdateStrategy.prompt,
checkOnLaunch: true,
promptCopy: PromptCopy(
title: 'New version available',
body: 'Update now for the latest features.',
updateButton: 'Update now',
laterButton: 'Maybe later',
),
);
}Dependencies
shorebird_updater_impl depends on shorebird_code_push: ^2.0.7. shorebird_updater_api depends only on equatable and the workspace's feature_sdk — no plugin dependency, so it's safe to import from anywhere.
Platform Setup
- Install the Shorebird CLI:bash
curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/install/main/install.sh -sSf | bash shorebird login- Generate this brick, then
cd apps/<app> && shorebird initto populateshorebird.yaml'sapp_id(auto-fills ifshorebirdAppIdwas left blank at generation time). - Commit
shorebird.yamlto version control.
Build-Prepare Ordering
Always run build-prepare with the build's own flavor before shorebird release/shorebird patch — Shorebird captures the dependency graph at build time, so this ensures it captures the production graph (noop implementations, no debug tools), not the internal one:
dart run monorepo_toolkit build-prepare --flavor production
shorebird release android --flavor production -- -t lib/main.dart
dart run monorepo_toolkit build-prepare --restore # back to developmentReleasing
# Initial release (creates the base release in Shorebird):
shorebird release android --flavor production -- -t lib/main.dart
shorebird release ios --flavor production -- -t lib/main.dart
# Subsequent patches (Dart-only changes):
shorebird patch android --flavor production
shorebird patch ios --flavor productionPatches only cover Dart-code changes — native code, assets, or plugin changes require a new release, not a patch.
CI Integration
When includeCiPatches = true, docs/shorebird-ci-patches.md is generated with ready-to-apply diffs for GitHub Actions (shorebirdtech/setup-shorebird action) and a Fastlane shorebird_build/shorebird_patch lane pair, both of which run build-prepare first. Required CI secret: SHOREBIRD_TOKEN (from shorebird token create). The doc is written once — if it already exists, generation skips it silently rather than overwriting local edits.
Limitations
- Shorebird requires a paid account for production usage at scale; a free tier exists for evaluation with limited monthly active users.
- Web and desktop targets are not supported —
isAvailablealways returnsfalseon web (kIsWebshort-circuits the check) and effectively on any platform Shorebird's engine doesn't support. - Two source comments (
// VERIFY: ...) inshorebird_updater_sdk_impl.dartflagReadPatchExceptionandShorebirdUpdater.update()'s throw behavior as pinned againstshorebird_code_pushv2.0.6 semantics specifically — worth re-checking against the actual^2.0.7+ resolved version if update checks start behaving unexpectedly.
Changelog
Run archipelago brick info shorebird_sdk to see the latest published version. Enterprise customers can read the full CHANGELOG.md in the brick source repository.