What it is: Local development server that runs on your Mac, live-reloading JavaScript changes.
When to use:
- ✅ Active development with rapid iteration
- ✅ Testing UI/logic changes without waiting for builds
- ✅ When you need instant feedback (press 'r' in terminal to reload)
- ✅ Network debugging with local breakpoints
Requirements:
- Mac server must be running (
npm startornpx expo start) - Device must be on same WiFi network OR plugged into Mac via USB
- App must be in development mode (not production builds)
Limitations:
- ❌ Cannot test native code changes (iOS/Android modifications)
- ❌ Requires device to stay connected to Mac
- ❌ Only works with development builds, not production builds
API Configuration:
- Points to
http://192.168.0.159:5100(your local Mac server) - Good for testing database changes and server logic locally
What it is: Push JavaScript/asset updates to existing builds without rebuilding the native app.
When to use:
- ✅ UI tweaks, text changes, styling adjustments
- ✅ Business logic updates (JavaScript/TypeScript only)
- ✅ Quick fixes that don't touch native code
- ✅ When you want to update multiple devices instantly
How to deploy:
cd mobile
npx eas update --branch staging --message "Description of changes"Requirements:
- Device must have internet connection
- App must be hard-closed and reopened to fetch update
- Build must have been created with the same
runtimeVersion
Limitations:
- ❌ Cannot update native iOS/Android code
- ❌ Cannot change build number, bundle ID, or native dependencies
- ❌ Cannot update Expo SDK version or native modules
- ❌ Users must relaunch app to receive update
API Configuration:
- Uses whatever API URL was baked into the original build
- Currently pointing to Heroku:
https://bloom-steward-2a872c497756.herokuapp.com
What it is: Creates complete iOS/Android app packages on Expo's cloud servers.
When to use:
- ✅ Native code changes (Info.plist, Xcode project, Android manifest)
- ✅ Adding/updating native dependencies (expo-location, react-native modules)
- ✅ Changing build number or version
- ✅ First-time installation or major releases
- ✅ When OTA updates aren't sufficient
How to build:
cd mobile
npx eas build --profile staging --platform iosBuild Profiles (defined in eas.json):
- Distribution: Internal (Ad Hoc)
- API URL: Heroku
- When prompted: EAS asks questions when credentials need updating or validation
- Use for: Testing builds before production
- Distribution: Internal (Ad Hoc)
- API URL: Heroku
- When prompted: Usually non-interactive after initial setup
- Use for: Main testing/QA builds
- Distribution: App Store
- API URL: Heroku
- When prompted: More validation before App Store submission
- Use for: Final App Store releases
Requirements:
- Device UDID must be registered in Apple Developer portal (for Ad Hoc)
- Takes 10-20 minutes to build on EAS servers
- Requires signing certificates and provisioning profiles
Installation:
- Open EAS build link on device (iPad/iPhone)
- Or use QR code to download
- iPad must be connected to WiFi to download build (cellular might work but WiFi is more reliable)
- iPad does NOT need to be plugged into Mac
Limitations:
- ❌ Slow feedback loop (10-20 min per build)
- ❌ Limited to 30 builds/month on free Expo plan
- ❌ Requires internet connection to build and download
What it is: Apple's official beta testing platform for iOS apps.
When to use:
- ✅ Distributing to external testers (up to 10,000)
- ✅ Testing App Store submission process
- ✅ When you need Apple's review before full release
- ✅ Production-like environment testing
How to submit:
cd mobile
npx eas build --profile production --platform ios
npx eas submit --platform iosRequirements:
- Build must pass Apple's automated review (can take hours)
- Testers must have TestFlight app installed
- Build must be signed with App Store distribution certificate
Limitations:
- ❌ Slower than EAS builds (Apple review delay)
- ❌ 90-day expiration per build
- ❌ More restricted environment (sandbox)
- ❌ Cannot use certain debugging features
What it is: Software simulation of iPhone/iPad running on your Mac.
When to use:
- ✅ Quick UI testing without physical device
- ✅ Testing different screen sizes/iOS versions
- ✅ Debugging with Xcode tools
How to run:
cd mobile
npx expo run:iosLimitations:
- ❌ Cannot test device-specific features (camera, GPS, push notifications)
- ❌ Performance differs from real devices
- ❌ Slower than physical devices for some operations
- ❌ Requires Xcode installed (40+ GB)
Current setup: All builds point to https://bloom-steward-2a872c497756.herokuapp.com
Reasons:
- Device Independence: iPad/iPhone work anywhere with internet
- Consistency: All testers use same backend
- Always Available: Heroku runs 24/7 (idle after 30 min, wakes on request)
- Production-like: Mimics real deployment environment
Alternative: Point to http://192.168.0.159:5100 (your Mac)
Reasons:
- Database Control: Easier to reset/seed data during development
- Faster Debugging: Direct access to server logs
- No Cold Starts: Local server responds instantly
- Offline Development: Works without internet
Problem: Device must be on same network as Mac, breaks when you leave home/Mac sleeps
- Pointed to
http://192.168.0.159:5100 - Fast iteration but brittle (network issues, Mac sleep, WiFi changes)
- Mixed configurations (some local, some Heroku)
- Network issues forced us to try different approaches
- Confusion about which build pointed where
- All builds now point to Heroku
- OTA updates work consistently
- More stable for testing
npx eas build --profile staging --platform ios --non-interactive- No questions asked if credentials are valid and up-to-date
- Uses cached certificates and provisioning profiles
npx eas build --profile staging --platform iosYou'll be prompted when:
-
Credentials Expired/Missing
- Distribution certificate expired (happens yearly)
- Provisioning profile needs updating (devices added/removed)
- First time building with EAS
-
Credential Validation
- EAS wants to verify credentials with Apple servers
- You're not logged into Apple Developer account in terminal
- Profile setting:
"credentialsSource": "local"requires manual input
-
Device Registration
- New device UDID detected for Ad Hoc builds
- Provisioning profile needs regeneration with new device
-
Build Profile Changes
- Switched from one profile to another (preview → staging → production)
- Different credentials required for different profiles
How to avoid questions:
- Use
--non-interactiveflag for automated builds - Keep credentials synced with
eas credentials - Use remote credentials managed by Expo (current setup)
- Don't change build profiles frequently
- Run Metro:
npm starton Mac - Connect device via WiFi or USB
- Press 'r' in terminal to reload after changes
- Advantage: Instant feedback, no waiting
- Start local server:
npm run build && npm start - Use Metro with device pointing to local server
- Or: Deploy to Heroku and use existing build
- Advantage: Full-stack testing
- Make changes to JavaScript/TypeScript
- Publish OTA:
npx eas update --branch staging --message "Fix description" - Users relaunch app to receive update
- Advantage: No rebuild needed, fast deployment
- Update build number in
ios/BloomSteward/Info.plist - Create new build:
npx eas build --profile staging --platform ios --non-interactive - Wait 10-20 minutes for build to complete
- Install on devices via download link
- Advantage: Full native code updates
- Build with production profile:
npx eas build --profile production --platform ios - Submit to TestFlight:
npx eas submit --platform ios - Wait for Apple review (hours to days)
- Distribute to testers via TestFlight app
- Advantage: Production environment, external testers
- Create base build with EAS pointing to Heroku (current setup)
- Deploy quickly with OTA updates for UI/logic fixes
- Rebuild only when native code changes or build number needs incrementing
- TestFlight for final pre-release validation before App Store
Never required for:
- Installing EAS builds (use download link over WiFi)
- Receiving OTA updates (over internet)
- TestFlight installation
Only required for:
- Xcode debugging with breakpoints
- Installing from Xcode directly (
npx expo run:ios --device) - Capturing device logs with Xcode Devices window
- Native iOS:
ios/BloomSteward/Info.plist→CFBundleVersion - NOT in:
app.json(ignored in bare workflow)
# Update to build 46
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion 46" mobile/ios/BloomSteward/Info.plist
# Verify
/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" mobile/ios/BloomSteward/Info.plist- App Store requires incrementing build numbers for each submission
- TestFlight requires unique build numbers
- EAS builds use this number (NOT app.json in bare workflow)
| Method | Speed | Native Code | Internet Required | Best For |
|---|---|---|---|---|
| Metro | ⚡ Instant | ❌ | Only for download | Active development |
| OTA Updates | 🔄 2-3 min | ❌ | ✅ | Quick fixes, UI tweaks |
| EAS Build | 🕐 10-20 min | ✅ | ✅ | Native changes, new features |
| TestFlight | 🕐 Hours-Days | ✅ | ✅ | Pre-release testing |
| Simulator | ⚡ Fast | ✅ | ❌ | UI/layout testing |
Need to make a change?
│
├─ Is it JavaScript/CSS only?
│ └─ YES → Use OTA Update (eas update)
│
├─ Is it native code (iOS files)?
│ └─ YES → Create new EAS Build
│
├─ Testing locally with frequent changes?
│ └─ YES → Use Metro (npm start + reload)
│
├─ Need to distribute to external testers?
│ └─ YES → Use TestFlight
│
└─ Just checking UI layout?
└─ YES → Use iOS Simulator
For Bloom Steward development:
- Keep Heroku as primary backend - More reliable than local server for testing
- Use OTA updates for 80% of changes (UI, logic, styling)
- Create new EAS builds only when necessary (native changes, version bumps)
- Use Metro locally when rapidly iterating on complex features
- TestFlight before App Store submission for final validation
- Never need cable for iPad - all installations work over WiFi
This setup minimizes build times while maintaining stability and flexibility.