Shipping a React Native App to TestFlight: The Part Nobody Shows
·~4 min·Programming · Tutorials
If you watch enough app dev content, you'd think the work ends when the UI looks good. The demo cuts right when the screens are pretty. But anyone who's actually shipped knows the real grind starts after that, in the unglamorous world of builds, signing, provisioning, and App Store Connect. This is the part nobody shows, so let's walk through it: how I get an Expo React Native app onto TestFlight, start to finish.
I'll be honest, this is also the exact part where my side projects go to die. Building is fun and creative. This part is procedural and a little intimidating, which is precisely why it's so easy to avoid. So the goal here is to demystify it, because once you've done it once, it stops being scary.
WHAT YOU NEED FIRST
- An Apple Developer account. It's $99 a year, and yes, you need it for TestFlight.
- An Expo project you can build.
- The EAS CLI installed and logged into your Expo account.
STEP 1: GET YOUR APP CONFIG RIGHT
Before any build, make sure your app.json, or app.config.js, has the essentials: a unique bundle identifier, your version, and a build number. The single most common thing that trips people up later is forgetting that every new upload to App Store Connect needs a higher build number than the last. Get in the habit early.
STEP 2: CONFIGURE EAS
Run eas build:configure once to set up your build profiles. This creates an eas.json with profiles like development, preview, and production. For TestFlight, you want a production-style build.
STEP 3: LET EAS HANDLE SIGNING
This is the step that scares everyone off, and it's the one EAS makes the easiest. When you kick off your first iOS build, EAS offers to manage your credentials for you, which means it generates and stores the distribution certificate and provisioning profile so you don't have to wrangle them by hand in the Apple Developer portal. Say yes. Manual signing is a rite of passage you do not need to suffer through anymore.
STEP 4: BUILD IT
eas build --platform ios --profile production
This runs the build on EAS's servers and spits out a signed .ipa. The first one takes a while, so grab a coffee. You'll get a link to the build when it's done.
STEP 5: SUBMIT TO APP STORE CONNECT
eas submit --platform ios
This uploads your finished build straight to App Store Connect. You'll point it at the build you just made, or let it grab the latest, and EAS handles the upload. No Xcode Organizer, no Transporter, no drama.
STEP 6: SET IT UP IN TESTFLIGHT
Over in App Store Connect, open your app and go to the TestFlight tab. A couple of things to expect here:
- Your build will sit in "Processing" for a bit after upload. This is normal. Go do something else.
- You'll have to answer the export compliance question about encryption. For most apps that just use HTTPS, this is a quick standard answer, but read it rather than clicking blindly.
- Once it's processed, add yourself and your testers as internal testers, and they'll get an invite to install through the TestFlight app.
That's it. Your app is on real devices.
THE GOTCHAS THAT'LL GET YOU
- Build numbers must always increase. Re-uploading the same number gets rejected.
- The first build is slow. Don't assume something's broken.
- App Store Connect loves a fresh agreement. If you've got an unsigned tax or paid-apps agreement sitting in your account, it can silently block things until you accept it.
- Export compliance will ask every build unless you set it once in your config.
WHY THIS MATTERS
Here's the thing I keep coming back to: this whole process is procedural, not creative. There's no taste involved, no clever design decision, nothing fun. And that's exactly why it's the hardest part of finishing a side project, because it asks for a different kind of effort than building does. But it's also completely learnable. Once you've walked the path a single time, getting the next app onto TestFlight is a 20-minute ritual instead of a wall.
So if you've got an app sitting at 90% on your machine, this is your nudge. The fun part is already done. This is just the last mile.
If you get stuck on a step, leave a comment or hit me up on Discord and I'll help you through it.