Skip to main content

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

1

Configure Build Profile

Add internal distribution profile to eas.json:
eas.json
Setting "distribution": "internal" automatically:
  • Android: Builds APK (directly installable) instead of AAB
  • iOS: Uses ad hoc or enterprise provisioning
2

Register iOS Devices (Ad Hoc Only)

For iOS ad hoc distribution, register test devices:
This opens a webpage where testers can:
  1. Visit the registration URL
  2. Download configuration profile
  3. Install profile to share UDID
Alternatively, manually add UDID:
Find device UDID:
  • Connect device to Mac
  • Open Finder > Select device
  • Click on serial number to show UDID
  • Right-click UDID to copy
3

Create Internal Build

This creates an APK that can be installed directly.
4

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
To share:
  1. Copy build URL from EAS CLI output
  2. Send to testers via email/Slack
  3. Testers scan QR code or visit URL on device
  4. Click Install button
iOS Installation:
  • Tap Install on build page
  • Confirm installation in Settings
  • Trust enterprise certificate if needed
Android Installation:
  • Download APK from build page
  • Allow installation from unknown sources
  • Install APK

Managing Device Access

List registered devices:
Remove device:
This prompts you to select device to remove. Optionally disables it on Apple Developer Portal.
Disabled devices still count toward Apple’s 100-device limit per year per app. Limit resets annually.
Rename device:
Gives friendly names to devices for easier management. Add device to existing build: After registering new devices, rebuild to include them:

Access Control

By default, internal builds are accessible to anyone with the URL. Require authentication:
  1. Go to Project Settings
  2. Find Unauthenticated access to internal builds
  3. Toggle OFF
Now testers must:
  • Have Expo account
  • Be added as collaborators to project
  • Sign in to download builds
Add collaborators:
  1. Go to project settings
  2. Navigate to Collaborators
  3. Add by Expo username or email
  4. Assign role (Admin, Developer, View Only)

TestFlight Distribution (iOS)

TestFlight is Apple’s beta testing platform built into App Store Connect.

Setting Up TestFlight

1

Build for TestFlight

TestFlight requires App Store builds (not ad hoc):
eas.json
Build and submit:
Or submit separately:
2

Wait for Processing

After submission:
  1. Build appears in App Store Connect
  2. Status: Processing (10-15 minutes)
  3. Status changes to Ready to Submit or Ready to Test
  4. Build available in TestFlight
3

Add Internal Testers

Internal testers (up to 100):
  • Must be added to App Store Connect
  • Can test immediately without review
  • Receive automatic updates
To add internal testers:
  1. Go to App Store Connect
  2. Select your app > TestFlight
  3. Under Internal Testing, click + next to Internal Testers
  4. Create group or add individual testers
  5. Select build to test
  6. Testers receive email invitation
4

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
To add external testers:
  1. Go to TestFlight > External Testing
  2. Click + to create new group
  3. Add build and release notes
  4. Enable Automatic Distribution for future builds
  5. Add testers by email
  6. Submit for Beta App Review
  7. After approval, testers receive invitations
5

Testers Install App

Testers need TestFlight app:
  1. Install TestFlight from App Store
  2. Open invitation email on iOS device
  3. Tap View in TestFlight
  4. Tap Install or Update
  5. App installs like any App Store app
TestFlight features for testers:
  • 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
Add notes in App Store Connect or via EAS:
Version management:
  • Increment build number for each TestFlight upload
  • Keep version number consistent (1.0.0) during testing
  • Only increment version for App Store release
Testing windows:
  • 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

1

Create Internal Testing Track

  1. Go to Google Play Console
  2. Select your app
  3. Navigate to Testing > Internal testing
  4. Click Create new release
2

Build and Submit

Configure submission in eas.json:
eas.json
Submit build:
3

Add Internal Testers

Create tester list:
  1. Go to Testing > Internal testing
  2. Click Testers tab
  3. Click Create email list
  4. Enter list name
  5. Add tester email addresses (comma-separated)
  6. Save list
Assign list to release:
  1. Go back to Internal testing
  2. Under release, click Manage testers
  3. Select your email list
  4. Save
4
Google Play provides unique opt-in URL:
  1. Copy URL from Internal testing page
  2. Share link with testers
  3. Testers open link on Android device
  4. Tap Become a tester
  5. Download app from Play Store
Link format:

Internal Testing Features

Fast deployments:
  • Updates available within minutes
  • No review process for internal track
  • Unlimited releases
Automatic updates:
  • Testers get updates via Play Store
  • Standard Play Store update flow
  • Can disable auto-update per app
Testing limits:
  • Up to 100 testers on internal track
  • For more testers, use Closed Testing (Alpha/Beta)
Crash reporting:
  • 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
Workflow:
  1. Development: EAS internal distribution for quick team testing
  2. Staging: TestFlight/Internal Testing for wider QA
  3. 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
Install Orbit:

Enterprise Distribution (iOS)

For large organizations with Apple Developer Enterprise Program:
eas.json
Benefits:
  • Unlimited device installations
  • No device UDID management
  • Suitable for internal corporate apps
  • Cannot be distributed on App Store
Requirements:
  • 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:
  1. Device not registered:
  2. Rebuild after adding device:
  3. Provisioning profile expired:
    • Regenerate credentials
    • Clear cache and rebuild

Android: “App not installed”

Issue: APK won’t install on Android Solutions:
  1. Enable unknown sources:
    • Settings > Security > Unknown sources
    • Or per-app permission on Android 8+
  2. Package conflict:
    • Uninstall existing version
    • Install new APK
  3. 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:
  1. Check tester is on email list
  2. Ensure release is active:
    • Status should be “Available”
    • Not “Draft” or “Halted”
  3. 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:
  1. Check URL is complete:
    • Should include full UUID
    • Format: https://expo.dev/accounts/.../builds/[uuid]
  2. Verify build completed:
  3. Check access controls:
    • If authentication required, tester needs Expo account
    • Add as project collaborator

Next Steps