Technically Speaking

TestFlight from ReactNative: How do you do it?


You have finally completed your awesome React Native app after the initial setup following our Technically Speaking article, Using GitHub with Expo and Vanilla React Native. Your next logical step is to test your app on your friends’ and family’s mobiles. On Android this is relatively straightforward. You can simply generate an APK and distribute using your website. But for iOS, you have to use the TestFlight platform to install the app on iPhones and iPads.

Before you get started, make sure you have an Apple Developer account, a MacOS device and a iPhone or iPad.

Firstly, we need to create an IPA build.

Setting up the developer account

Make sure you have signed in at least once to iTunes Connect using the same account you will be using to upload the app to the App Store.

To upload your app to the App Store, we will be using a macOS app called Transporter. After that, make sure you enrol to the Apple Developer Program.

Creating an IPA build

We need specifically an archive build to deploy on TestFlight. For this, we can run the Expo command;

expo build:ios -t archive

Then, Expo will then create an IPA file – you can upload this either to the App Store or TestFlight.

The CLI will prompt you to provide other information as well:

  • Will you provide your own Apple Distribution Certificate?
  • Will you provide your own Apple Push Notifications service key?
  • Will you provide your own Apple Provisioning Profile?

For all these questions you can opt to let Expo handle these for you.

If you receive an error like this, just re-install Expo by running

npm i -g exp
Expo terminal window showing a common gotcha

If the problem still exists, make sure you are on the latest version of expo by running:

npm install -g expo-cli

Examples of other errors that occurred and their how to resolve them:

To resolve this, simply delete the .fastlane folder at the path given in the error message.

Uploading IPA to Transporter APP

Firstly, you need to create an App Store listing for the app. To do this, visit and choose to add a “New App”. Specify the name and other details. Select the bundle ID that has the bundle ID you specified during the IPA creation process.

Finally! This is the final step before you can get to see the app on your iOS home screen. This step is simple. You simply drag the IPA file and drop it on the Transporter app.

If everything went well, you can see a nice blue deliver button. Press this!

Press the 'Deliver' button to submit the IPA to the App Store an TestFlight
Press the ‘Deliver’ button to submit the IPA to the App Store an TestFlight

Setting up external testing on TestFlight

You can now view the app on App Store Connect. Open your app listing on App Store connect. This page will have a tab named “TestFlight”. Before you can deploy the app to external testers, you need to fill in some required information.

Fill in the required TestFlight information
Fill in the required TestFlight information

Then, the Builds section will show that your app is being processed. Afterwards, you can start internal testing by supplying the Apple account addresses.

Technically Speaking

Using GitHub with Expo and Vanilla React Native


One of the major disadvantages of making use of Expo is when you have to stop using it – when you come across a missing feature in Expo. The only option left is to eject from the Expo workflow and move to a vanilla react-native stack. Any SDKs you borrowed from Expo can be added using ExpoKit. This immediately sounds like a lot of work and we will discuss about a workflow to integrate both Expo and react-native using GitHub.

About the Project

I am writing this while I am in the process of adapting one of my projects to this new workflow – to say the least, I am learning as I am writing; I am writing as I am learning. This would serve as a personal reference as well while sharing my process with other fellow developers so that they can run where I, crawled.

The project started as a test project but quickly evolved into a financially backed contract. I had not integrated GitHub to the initial project either. What I had was two separate folders. One for the react-native workflow and one for the Expo workflow. Modifications that had a native module part was done in the react-native distribution while using Expo for the UI/ UX modifications and other logic that did not require the custom modules to function. The custom module I wanted to use was react-native-nfc-manager – Expo does not support NFC features as of now.

Expo is a tool at Orpheus that we can not live without. Due to this, we have a bunch of other tutorials that delve into great depths about Expo like the implementation of material design in Expo-based apps.

Using expo eject

A feature introduced in SDK 34 upwards is the ability to eject to what Expo terms a bare workflow. Initially you could only eject to an ExpoKit workflow. Personally, not having used this workflow, I will refrain from commenting on its functionality. But seeing that the folks at Expo are phasing it out and recommending new users eject to bare workflow, I would say that ExpoKit was not successful at its job. What happens to any Expo-based APIs and libraries? The process of moving to the bare workflow will also move the Expo libraries already in use. This is an automatic process.

The beautiful thing with the new bare workflow environment is that it allows you to use the Expo client as long as Native code is restricted from running. Expo provides an API call to detect if the app is running in an Expo mobile client or as a vanilla app.

To eject, simply run,

expo eject
A screenshot showing the manual steps of the eject command used on a GitHub repo project
A screenshot showing the manual steps of the eject command

Do not forget to select “Bare” from the options that come up.

To run the project as an Expo app, simply run –

expo start

Adding native plugins

The next logical step is to add a plugin that is based on native code. In other words, a plugin that would not be able to be added in a managed Expo environment.

The plugin we will use to test this is react-native-nfc-manager plugin. To add this plugin, we use the yarn add command as shown below:

yarn add react-native-nfc-manager --save

To run the app as a vanilla React Native app on a mobile connected via USB, simply execute the following command –

yarn android

Committing to GitHub

Another question that would arise at this point of the process is what folders should be committed to GitHub. The easiest method is to use the online service. This website allows you to select your technology stack to produce a gitignore file. For your easiness, we have already selected and produced a .gitignore file for use on Windows or macOS stacks:,windows,reactnative

The most significant change is that the certain files from android and ios folders (that were made during the eject process) are also chosen to be synced. Commits will exclude build-related files and folders. These files are auto-generated from the source.

Cloning from GitHub

After cloning the repository to a local folder, we need to install the libraries and instantiate Expo (basically, re-creating the node_modules folder) . To do this, you will only require one command:

npm install

Library and script downloads will take some time. After that, we can run it on Expo using;

expo start

Or if we want to check native code and run vanilla React Native, simply run;

yarn android
yarn ios

Sometimes the react-native builder fails to recognize the Android SDK directory. In that case you can set an environment variable pointing to the directory (command shown for Windows):

set ANDROID_HOME=C:\Users\<UserName>\AppData\Local\Android\sdk

The placeholder <UserName> should be replaced with the user’s Windows profile directory name.

We do not have to perform expo eject as our commits already contain an ‘ejected’ work space.

This concludes the Technically Speaking post for today. Hope you learnt something from the post!