Internal Distribution
Internal distribution allows you to share your app with team members and testers before submitting to public app stores. This is essential for quality assurance, stakeholder reviews, and beta testing.Distribution Methods Overview
EAS Build Internal Distribution
Best for: Quick sharing with small teams- Direct download URLs for builds
- No app store accounts needed for testers
- Works on both iOS (ad hoc) and Android (APK)
- Install via QR code or link
- Up to 100 iOS devices per year (Apple limitation)
TestFlight (iOS)
Best for: Large-scale iOS beta testing- Up to 10,000 external testers
- Distributed through App Store infrastructure
- Automatic updates for testers
- Crash reports and feedback
- Requires App Store Connect account
Google Play Internal Testing (Android)
Best for: Android beta testing via Play Store- Up to 100 internal testers
- Distributed through Play Store
- Fast updates (available within minutes)
- Automatic crash reporting
- Requires Google Play Console
EAS Build Internal Distribution
Setting Up Internal Distribution
Configure Build Profile
Add internal distribution profile to eas.json:eas.json
"distribution": "internal" automatically:- Android: Builds APK (directly installable) instead of AAB
- iOS: Uses ad hoc or enterprise provisioning
Register iOS Devices (Ad Hoc Only)
For iOS ad hoc distribution, register test devices:- Visit the registration URL
- Download configuration profile
- Install profile to share UDID
- Connect device to Mac
- Open Finder > Select device
- Click on serial number to show UDID
- Right-click UDID to copy
Create Internal Build
- Tab Title
- Tab Title
- Tab Title
Share Build with Testers
After build completes, EAS provides:- Build URL:
https://expo.dev/accounts/[account]/projects/[project]/builds/[id] - QR Code: For easy mobile access
- Direct download link: For installing the app
- Copy build URL from EAS CLI output
- Send to testers via email/Slack
- Testers scan QR code or visit URL on device
- Click Install button
- Tap Install on build page
- Confirm installation in Settings
- Trust enterprise certificate if needed
- Download APK from build page
- Allow installation from unknown sources
- Install APK
Managing Device Access
List registered devices:Access Control
By default, internal builds are accessible to anyone with the URL. Require authentication:- Go to Project Settings
- Find Unauthenticated access to internal builds
- Toggle OFF
- Have Expo account
- Be added as collaborators to project
- Sign in to download builds
- Go to project settings
- Navigate to Collaborators
- Add by Expo username or email
- Assign role (Admin, Developer, View Only)
TestFlight Distribution (iOS)
TestFlight is Apple’s beta testing platform built into App Store Connect.Setting Up TestFlight
Build for TestFlight
TestFlight requires App Store builds (not ad hoc):eas.json
Wait for Processing
After submission:- Build appears in App Store Connect
- Status: Processing (10-15 minutes)
- Status changes to Ready to Submit or Ready to Test
- Build available in TestFlight
Add Internal Testers
Internal testers (up to 100):- Must be added to App Store Connect
- Can test immediately without review
- Receive automatic updates
- Go to App Store Connect
- Select your app > TestFlight
- Under Internal Testing, click + next to Internal Testers
- Create group or add individual testers
- Select build to test
- Testers receive email invitation
Add External Testers (Optional)
External testers (up to 10,000):- Anyone with Apple ID
- Requires Beta App Review (1-2 days)
- Great for public beta testing
- Go to TestFlight > External Testing
- Click + to create new group
- Add build and release notes
- Enable Automatic Distribution for future builds
- Add testers by email
- Submit for Beta App Review
- After approval, testers receive invitations
Testers Install App
Testers need TestFlight app:- Install TestFlight from App Store
- Open invitation email on iOS device
- Tap View in TestFlight
- Tap Install or Update
- App installs like any App Store app
- View release notes
- Send feedback via screenshots
- Check for updates
- Stop testing anytime
TestFlight Best Practices
Release notes: Include clear notes for each build:eas.json
- Increment build number for each TestFlight upload
- Keep version number consistent (
1.0.0) during testing - Only increment version for App Store release
- TestFlight builds expire after 90 days
- Upload new builds regularly for ongoing testing
- Testers automatically get updates if enabled
Google Play Internal Testing (Android)
Setting Up Internal Testing
Create Internal Testing Track
- Go to Google Play Console
- Select your app
- Navigate to Testing > Internal testing
- Click Create new release
Add Internal Testers
Create tester list:- Go to Testing > Internal testing
- Click Testers tab
- Click Create email list
- Enter list name
- Add tester email addresses (comma-separated)
- Save list
- Go back to Internal testing
- Under release, click Manage testers
- Select your email list
- Save
Share Testing Link
Google Play provides unique opt-in URL:- Copy URL from Internal testing page
- Share link with testers
- Testers open link on Android device
- Tap Become a tester
- Download app from Play Store
Internal Testing Features
Fast deployments:- Updates available within minutes
- No review process for internal track
- Unlimited releases
- Testers get updates via Play Store
- Standard Play Store update flow
- Can disable auto-update per app
- Up to 100 testers on internal track
- For more testers, use Closed Testing (Alpha/Beta)
- Automatic crash collection
- View in Play Console > Quality > Crashes
- Pre-launch reports available
Advanced Internal Distribution
Multiple Testing Tracks
Manage different testing stages:eas.json
- Development: EAS internal distribution for quick team testing
- Staging: TestFlight/Internal Testing for wider QA
- Production: Full store release
Automated Internal Releases
Use EAS Workflows to automate internal builds:.eas/workflows/preview.yml
Using Expo Orbit
Expo Orbit is a macOS/Windows menubar app for managing builds: Features:- View all EAS builds
- One-click install to simulator/emulator
- Download builds locally
- Launch apps quickly
- Perfect for team testing
Enterprise Distribution (iOS)
For large organizations with Apple Developer Enterprise Program:eas.json
- Unlimited device installations
- No device UDID management
- Suitable for internal corporate apps
- Cannot be distributed on App Store
- Apple Developer Enterprise Program membership ($299/year)
- DUNS number
- Legal entity with 100+ employees
Troubleshooting
iOS: “Unable to Download App”
Issue: Testers can’t install ad hoc build Solutions:-
Device not registered:
-
Rebuild after adding device:
-
Provisioning profile expired:
- Regenerate credentials
- Clear cache and rebuild
Android: “App not installed”
Issue: APK won’t install on Android Solutions:-
Enable unknown sources:
- Settings > Security > Unknown sources
- Or per-app permission on Android 8+
-
Package conflict:
- Uninstall existing version
- Install new APK
-
Architecture mismatch:
- Ensure APK built for correct architecture
- Use universal APK for compatibility
TestFlight: “Build is missing compliance”
Issue: Export compliance warning Solution: Add to app.json:Play Console: “Tester can’t find app”
Issue: Tester visited opt-in link but can’t download Solutions:- Check tester is on email list
- Ensure release is active:
- Status should be “Available”
- Not “Draft” or “Halted”
- Wait for propagation:
- Can take 5-10 minutes
- Ask tester to refresh Play Store
Build URL not working
Issue: Testers get 404 on build URL Solutions:-
Check URL is complete:
- Should include full UUID
- Format:
https://expo.dev/accounts/.../builds/[uuid]
-
Verify build completed:
-
Check access controls:
- If authentication required, tester needs Expo account
- Add as project collaborator
Next Steps
- Over-the-Air Updates - Push updates to testers instantly
- Build Configuration - Optimize build profiles
- App Stores - Graduate from testing to production