Skip to content
Back to archipelago.banuacoder.com

Feature SDKs (Pro)

shorebird_sdk Pro ​

Tier
Proversion 1.1.8
Command
archipelago generate shorebird_sdk
Generates
  • features/shorebird/shorebird_updater_api
  • features/shorebird/shorebird_updater_impl
Depends on
shared_identifiersgenerate these first

OTA code-push SDK wrapping shorebird_code_push. Generates shorebird_updater_api (contract + sealed result models) and shorebird_updater_impl (ShorebirdUpdater wrapper 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 ​

VariableTypeDefaultDescription
shorebirdAppIdstring""Your Shorebird app_id from shorebird init or the dashboard. Leave blank to fill in shorebird.yaml manually.
includeCiPatchesbooleantrueGenerate docs/shorebird-ci-patches.md with sample diffs for CI integration.

Install ​

Interactive ​

bash
archipelago generate shorebird_sdk

Non-interactive (CI) ​

bash
archipelago generate shorebird_sdk --config my_config.json

pre_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 ​

text
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 = true

Public API ​

dart
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:

dart
@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 ​

  1. Install the Shorebird CLI:
    bash
    curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/install/main/install.sh -sSf | bash
  2. shorebird login
  3. Generate this brick, then cd apps/<app> && shorebird init to populate shorebird.yaml's app_id (auto-fills if shorebirdAppId was left blank at generation time).
  4. Commit shorebird.yaml to 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:

bash
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 development

Releasing ​

bash
# 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 production

Patches 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 — isAvailable always returns false on web (kIsWeb short-circuits the check) and effectively on any platform Shorebird's engine doesn't support.
  • Two source comments (// VERIFY: ...) in shorebird_updater_sdk_impl.dart flag ReadPatchException and ShorebirdUpdater.update()'s throw behavior as pinned against shorebird_code_push v2.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.