How to Distribute React Native Apps to Testers
React Native teams build once and test twice. You write a single codebase, but the moment you need to get a build onto a tester’s phone, you’re dealing with two platforms, two build systems, and two very different distribution headaches. The distribution step shouldn’t be the bottleneck that slows your release cycle.
Whether you’re running a bare React Native project or using Expo’s managed workflow, getting test builds into your team’s hands quickly is what separates teams that ship fast from teams stuck waiting on TestFlight review queues. In this guide, we’ll walk through building release artifacts from both workflows, uploading them for distribution, automating the process with CI/CD, and how the available tools stack up against each other.
Expo vs. Bare Workflow: Both Produce APK and IPA
Before we get into distribution, let’s clarify something: regardless of whether you’re using the bare React Native CLI or Expo’s managed workflow, the end result is the same, an .apk file for Android and an .ipa file for iOS. These are the standard binary formats that any distribution platform, including TestApp.io, can work with.
The difference is how you produce those files, not what you produce.
Building Release Artifacts: Bare Workflow
Android (APK)
For a bare React Native project, building a release APK is done through Gradle. From your project root:
cd android
./gradlew clean
./gradlew assembleReleaseBefore this works, you need a signing keystore configured in android/app/build.gradle. If you haven’t set one up yet, generate it with:
keytool -genkeypair -v -storetype PKCS12 \
-keystore my-upload-key.keystore \
-alias my-key-alias -keyalg RSA \
-keysize 2048 -validity 10000Your signed APK will be at android/app/build/outputs/apk/release/app-release.apk.
iOS (IPA)
For iOS, you’ll need a Mac with Xcode installed. Open your .xcworkspace file:
open ios/YourApp.xcworkspaceThen:
- Set the active scheme to Release (Product → Scheme → Edit Scheme → set Build Configuration to Release).
- Select Any iOS Device (arm64) as the build target.
- Go to Product → Archive.
- Once the archive completes, click Distribute App and choose Ad Hoc or Development distribution to export an
.ipafile.
For command-line builds (useful in CI), you can use xcodebuild:
xcodebuild -workspace ios/YourApp.xcworkspace \
-scheme YourApp \
-configuration Release \
-archivePath build/YourApp.xcarchive \
archive
xcodebuild -exportArchive \
-archivePath build/YourApp.xcarchive \
-exportPath build/ \
-exportOptionsPlist ExportOptions.plistBuilding Release Artifacts: Expo (EAS Build)
If you’re using Expo, EAS Build handles the compilation in the cloud, no local Android Studio or Xcode required for Android builds.
First, install the EAS CLI and configure your project:
npm install -g eas-cli
eas build:configureTo build installable binaries for tester distribution, set your eas.json build profile to use internal distribution:
{
"build": {
"preview": {
"distribution": "internal",
"android": {
"buildType": "apk"
},
"ios": {
"simulator": false
}
}
}
}Then build for both platforms:
eas build --profile preview --platform allThis produces an .apk for Android and an .ipa for iOS. Once the builds complete, download them from the EAS dashboard or CLI output.
"distribution": "internal" tells EAS to produce an APK for Android and an ad-hoc signed IPA for iOS. This is exactly what you need for tester distribution outside the app stores.Uploading to TestApp.io
Once you have your .apk and .ipa files, you have three ways to get them to your testers through TestApp.io:
1. Portal Upload (Manual)
The simplest approach: log into the TestApp.io Portal, navigate to your app, and drag-and-drop your build file. Your team gets notified instantly, and testers can install the build directly from their device’s browser, no app store review, no waiting.
2. CLI Upload (ta-cli)
For developers who prefer the command line, ta-cli lets you publish directly from your terminal:
ta-cli publish \
--api_token YOUR_API_TOKEN \
--app_id YOUR_APP_ID \
--release both \
--apk ./android/app/build/outputs/apk/release/app-release.apk \
--ipa ./build/YourApp.ipa \
--release_notes "Fixed login bug, updated onboarding flow" \
--notify \
--git_release_notes \
--git_commit_idKey flags:
--release:android,ios, orboth--apk/--ipa: Path to your build artifact--release_notes: What changed in this build (up to 1,200 characters)--notify: Automatically notify your team members--git_release_notes: Append the latest git commit message to release notes--git_commit_id: Include the git commit hash in release notes--archive_latest_release: Automatically archive the previous release on upload
Generate your API token from Portal Settings → API Credentials.
3. CI/CD Integration (Automated)
This is where it gets powerful. Wire up your CI/CD pipeline to build and distribute on every push. No manual steps, no forgotten uploads, your testers always have the latest build.
CI/CD: GitHub Actions Workflow for React Native + TestApp.io
Here’s a complete GitHub Actions workflow that builds a React Native Android APK and uploads it to TestApp.io automatically:
Full setup guide: GitHub Actions setup guide
For iOS, you’d add a separate job running on macos-latest with the Xcode archive steps, or use Fastlane to simplify the iOS build and signing process.
Expo + EAS + GitHub Actions
If you’re using Expo, your workflow is even simpler since EAS Build handles the compilation remotely:
Full setup guide: GitHub Actions with Expo EAS guide
How TestApp.io Compares to the Alternatives
Let’s be real: there are other ways to get builds to testers. Here’s how they compare for React Native teams:
| TestApp.io | TestFlight | Expo EAS Update | |
|---|---|---|---|
| Android support | ✅ APK upload | ❌ iOS only | ✅ JS-only OTA |
| iOS support | ✅ IPA upload | ✅ Full support | ✅ JS-only OTA |
| Review required | No | Yes (first build per version) | No |
| Native code changes | ✅ Full binary | ✅ Full binary | ❌ JS bundle only |
| Setup complexity | Low. upload and share | Medium. Apple Developer account, provisioning | Medium. Expo ecosystem required |
| CI/CD integration | ✅ GitHub Actions, Fastlane, CLI | ✅ Via Xcode / Fastlane | ✅ Built-in EAS workflows |
| Team notifications | ✅ Built-in (Slack, Teams, email) | ❌ Manual or via App Store Connect | ❌ Manual |
| Tester device management | ✅ UDID collection + provisioning | ✅ Via Apple Developer portal | ❌ Not applicable (OTA) |
| Cost | Free tier available. see pricing | Requires $99/yr Apple Developer account | Free tier + paid plans |
A Note on CodePush
If you’re reading older React Native guides, you’ll see references to CodePush for over-the-air updates. CodePush is no longer available. Microsoft retired Visual Studio App Center on March 31, 2025, and CodePush went down with it. While Microsoft open-sourced the CodePush server for self-hosting, that’s a significant operational burden for most teams.
For OTA JavaScript bundle updates, Expo’s EAS Update is a solid alternative. But for distributing full native builds, which you need any time you change native modules, update React Native versions, or modify native configuration, you need a proper binary distribution tool.
Why Not Just Use TestFlight?
TestFlight is great for what it does, but it comes with friction for React Native teams:
- iOS only. You still need a separate solution for Android. React Native teams need to test on both platforms.
- Review delays. Your first build of each version goes through Apple’s review, which can take hours to days.
- 90-day expiry. Builds expire after 90 days from upload.
- Apple Developer account required. $99/year, and every tester needs to be invited through App Store Connect.
- No built-in team notifications. You can’t automatically ping your Slack channel or Teams group when a new build is ready.
TestApp.io handles both platforms from one dashboard, with no review queue, instant installation links, and built-in notifications to Slack and Microsoft Teams.
Putting It All Together
Here’s the workflow that React Native teams use to eliminate distribution as a bottleneck:
- Develop in your React Native codebase as usual.
- Push to your main or develop branch.
- CI builds your APK and IPA automatically (GitHub Actions, Codemagic, or your CI of choice).
- ta-cli or the GitHub Action uploads the artifacts to TestApp.io.
- Testers get notified via Slack, Teams, or email and install the build in one tap.
- Feedback comes back fast, and you iterate on the next build.
No app store reviews. No waiting. No “can you re-send me the build?” messages in Slack.
Get Started
TestApp.io has a free tier that covers small teams, and setup takes about five minutes. Create your account, add your app, generate an API token, and you’re distributing.
Related Articles
- How to Distribute Flutter Apps to Testers
- TestFlight vs TestApp.io: A Direct Comparison
- Google Play Internal Testing Alternative
- How to Automate Mobile App Distribution with CI/CD
- Best Mobile App Distribution Platforms in 2026
If you’re already using CI/CD, add the GitHub Action or drop ta-cli into your pipeline script. Your testers will thank you.