Table of Contents
- What is Shorebird?
- Why You Need It
- Prerequisites
- Installation
- Setup & Configuration
- Creating Your First Release
- Deploying Patches
- CI/CD Integration
- Best Practices
- Troubleshooting
What is Shorebird?
Shorebird is a code push solution for Flutter that lets you update your app's Dart code without going through the Apple App Store or Google Play Store review process.
Think of it as hotfix superpowers for production apps. Bug in production? Deploy a patch in minutes instead of waiting days for app store approval.
Key Capabilities:
- ✅ Push Dart code updates instantly
- ✅ Bypass app store review cycles
- ✅ Automated rollback on crashes
- ✅ Staged rollouts (release to 5%, then 50%, then 100%)
- ✅ Detailed analytics on patch adoption
- ✅ Works with Flutter's native capabilities
Why You Need It
Scenario: It's Friday evening. Your production app has a critical bug affecting checkout. Users are losing money.
Without Shorebird:
- Submit fix to Apple App Store
- Wait 24-48 hours for review
- Users suffer the entire time
- Potential revenue loss
With Shorebird:
- Deploy fix in 5 minutes
- Users get the patch immediately
- Crisis averted
Real-World Benefits:
- Reduce Time-to-Market: Deploy hotfixes without waiting for store approval
- Better User Experience: Critical bugs fixed instantly
- Cost Savings: Fewer production incidents = fewer support tickets
- Faster Iteration: Deploy A/B tests and feature toggles in real-time
- CI/CD Integration: Automate patch deployment through your pipeline
Prerequisites
Before starting, ensure you have:
- Flutter Project: An existing Flutter app (or create one)
flutter create my_app
cd my_app
Shorebird Account: Sign up at shorebird.dev
Flutter SDK: Version 3.0 or higher
flutter --version
- Git: For version control
git --version
-
Platform Requirements:
- iOS: Xcode 14+
- Android: Android SDK 21+
Installation
Step 1: Install Shorebird CLI
# On macOS/Linux
curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/shorebird/main/scripts/install.sh | bash
# On Windows (PowerShell)
iwr https://raw.githubusercontent.com/shorebirdtech/shorebird/main/scripts/install.ps1 -UseBasicParsing | iex
Step 2: Verify Installation
shorebird --version
Expected output:
Shorebird 0.x.x
Step 3: Initialize Shorebird in Your Project
cd your_flutter_project
shorebird init
This creates:
-
.shorebird/config.yaml- Shorebird configuration - Updates
pubspec.yamlwith dependencies
Setup & Configuration
Step 1: Authenticate with Shorebird
shorebird login
This opens a browser window for authentication. Sign in with your Shorebird account.
Step 2: Review shorebird.yaml
Located in your project root:
app_id: "your-app-id-here"
flavors:
- name: production
app_id: "prod-app-id"
Step 3: Update Your App Version
In pubspec.yaml:
version: 1.0.0+1 # version+build_number
Important: Increment the build number for each Shorebird release.
Step 4: Configure Your App
In lib/main.dart, ensure your app can handle code updates:
import 'package:shorebird_code_push/shorebird_code_push.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Optional: Check for updates on app start
final codePush = ShorebirdsCodePush();
await codePush.checkForUpdates();
runApp(const MyApp());
}
Creating Your First Release
Step 1: Build for Release
Before creating a Shorebird release, build your app for both platforms.
For Android:
shorebird build apk --release
For iOS:
shorebird build ipa --release
Step 2: Review Build Output
Successful output looks like:
✓ Built APK: build/app/outputs/flutter-app-release.apk
✓ Built IPA: build/ios/ipa/MyApp.ipa
Step 3: Submit to App Stores
Google Play Store:
fastlane supply --apk build/app/outputs/flutter-app-release.apk
Or upload manually via Google Play Console.
Apple App Store:
fastlane pilot upload --ipa build/ios/ipa/MyApp.ipa
Or use Xcode/Transporter.
Step 4: Create a Release in Shorebird
Once your app is live on stores:
shorebird release
This captures the current code state as your baseline release.
Deploying Patches
Scenario: You have a bug fix ready
Step 1: Make Your Code Changes
Fix the bug in your Dart code:
// Before
class LoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// BUG: Email validation broken
return TextField(
onChanged: (value) => emailValidation(value),
);
}
}
// After
class LoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// FIXED: Proper email validation
return TextField(
onChanged: (value) => _validateEmail(value),
);
}
void _validateEmail(String email) {
final regex = RegExp(r'^[^@]+@[^@]+\.[^@]+');
return regex.hasMatch(email);
}
}
Step 2: Bump the Build Number
In pubspec.yaml:
# Before
version: 1.0.0+1
# After
version: 1.0.0+2
Step 3: Create a Patch
shorebird patch
Shorebird will:
- Build the patched code
- Compare it to the release baseline
- Create a minimal delta package
- Upload it to Shorebird servers
Step 4: Monitor Patch Status
shorebird patch status
Output shows:
- Patch creation status
- Percentage of devices updated
- Any errors or rollbacks
Step 5: Staged Rollout (Optional)
Deploy to a small percentage first:
shorebird patch --staged-rollout 0.05
# Deploys to 5% of users
Monitor for 24 hours, then increase:
shorebird patch --staged-rollout 0.5
# Deploys to 50% of users
Finally, roll out to everyone:
shorebird patch --staged-rollout 1.0
# 100% rollout
CI/CD Integration
GitHub Actions Example
Create .github/workflows/shorebird-patch.yml:
name: Shorebird Patch Deployment
on:
workflow_dispatch:
inputs:
staged_rollout:
description: 'Staged rollout percentage (0.0-1.0)'
required: false
default: '1.0'
jobs:
patch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.x'
- name: Install Shorebird
run: |
curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/shorebird/main/scripts/install.sh | bash
- name: Authenticate Shorebird
run: shorebird login --token ${{ secrets.SHOREBIRD_TOKEN }}
- name: Create Patch
run: shorebird patch --staged-rollout ${{ github.event.inputs.staged_rollout || '1.0' }}
- name: Notify Slack
uses: slackapi/slack-github-action@v1
with:
webhook-url: ${{ secrets.SLACK_WEBHOOK }}
payload: |
{
"text": "✅ Shorebird patch deployed successfully!",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Shorebird Patch Deployed\nRollout: ${{ github.event.inputs.staged_rollout || '100%' }}\nRef: ${{ github.ref }}"
}
}
]
}
GitLab CI Example
Create .gitlab-ci.yml:
patch:shorebird:
stage: deploy
image: google/flutter:latest
script:
- curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/shorebird/main/scripts/install.sh | bash
- shorebird login --token $SHOREBIRD_TOKEN
- shorebird patch --staged-rollout 0.5
only:
- main
when: manual
Best Practices
1. Test Before Patching
Always test your code locally and in staging:
flutter test
flutter analyze
flutter run --release
2. Use Semantic Versioning
# Major.Minor.Patch+BuildNumber
version: 1.2.3+45
3. Document Your Patches
Create a CHANGELOG:
## [1.2.3] - 2024-06-07
### Fixed
- Fixed email validation bug in login screen
- Corrected typo in onboarding flow
- Resolved memory leak in metrics tracker
### Changed
- Improved error messages for better UX
4. Staged Rollouts for Critical Patches
Never roll out 100% immediately:
# Day 1: 5%
shorebird patch --staged-rollout 0.05
# Day 2: 25%
shorebird patch --staged-rollout 0.25
# Day 3: 100%
shorebird patch --staged-rollout 1.0
5. Monitor Metrics
Check adoption and error rates:
shorebird patch status --verbose
6. Have a Rollback Plan
If a patch causes issues:
shorebird patch rollback
Troubleshooting
Issue: "App ID not found"
Solution:
shorebird init # Re-initialize
shorebird login # Re-authenticate
Issue: "Patch failed: No changes detected"
Cause: No Dart code changes since last release.
Solution:
# Ensure build number is incremented
version: 1.0.0+2 # Changed from +1
Issue: "Users not receiving patch"
Cause: App not checking for updates.
Solution: Add to main.dart:
final codePush = ShorebirdsCodePush();
await codePush.checkForUpdates();
Issue: "Staged rollout stuck at X%"
Solution:
shorebird patch status --verbose
shorebird patch resume # Resume rollout
Issue: "Build fails on iOS"
Solution:
cd ios
pod repo update
pod install
cd ..
flutter clean
shorebird build ipa --release
Summary
Shorebird transforms how you deploy Flutter apps:
| Feature | Without Shorebird | With Shorebird |
|---|---|---|
| Hotfix Time | 24-48 hours | 5 minutes |
| User Experience | Bugs persist | Instant fixes |
| A/B Testing | Requires app update | Real-time |
| Rollback | Requires new submission | Instant |
| Cost | High (support tickets) | Low (automated) |
Next Steps
- Visit: https://shorebird.dev/
- Read: Shorebird documentation
- Try: Create your first patch
- Integrate: Add to your CI/CD pipeline
- Deploy: Ship faster, update smarter
Resources
- 📖 Official Docs: https://docs.shorebird.dev/
- 🐛 GitHub Issues: https://github.com/shorebirdtech/shorebird
- 💬 Discord Community: https://discord.gg/shorebird
- 📺 Video Guide: https://www.youtube.com/watch?v=EIiBDoVHlNc&t=10s
Happy patching! 🚀
Top comments (0)