Running On Device

It's always a good idea to test your app on an actual device before releasing it to your users. This document will guide you through the necessary steps to run your React Native app on a device and to get it ready for production.

If you used Create React Native App to set up your project, you can preview your app on a device by scanning the QR code with the Expo app. In order to build and run your app on a device, you will need to eject and install the native code dependencies from the Getting Started guide.

iOS

Android

Running your app on iOS devices

Running your app on Android devices

A Mac is required in order to build your app for iOS devices. Alternatively, you can refer to the Quick Start instructions to learn how to build your app using Create React Native App, which will allow you to run your app using the Expo client app.

1. Plug in your device via USB

Connect your iOS device to your Mac using a USB to Lightning cable. Navigate to the ios folder in your project, then open the .xcodeproj file, or if you are using CocoaPods open .xcworkspace, within it using Xcode.

If this is your first time running an app on your iOS device, you may need to register your device for development. Open the Product menu from Xcode's menubar, then go to Destination. Look for and select your device from the list. Xcode will then register your device for development.

2. Configure code signing

Select your project in the Xcode Project Navigator, then select your main target (it should share the same name as your project). Look for the "General" tab. Go to "Signing" and make sure your Apple developer account or team is selected under the Team dropdown.

Repeat this step for the Tests target in your project.

3. Build and Run your app

If everything is set up correctly, your device will be listed as the build target in the Xcode toolbar, and it will also appear in the Devices pane (⇧⌘2). You can now press the Build and run button (⌘R) or select Run from the Product menu. Your app will launch on your device shortly.

1. Enable Debugging over USB

Most Android devices can only install and run apps downloaded from Google Play, by default. You will need to enable USB Debugging on your device in order to install your app during development.

To enable USB debugging on your device, you will first need to enable the "Developer options" menu by going to Settings → About phone and then tapping the Build number row at the bottom seven times. You can then go back to Settings → Developer options to enable "USB debugging".

2. Plug in your device via USB

Let's now set up an Android device to run our React Native projects. Go ahead and plug in your device via USB to your development machine.

Next, check the manufacturer code by using lsusb (on mac, you must first install lsusb). lsusb should output something like this:

3. Run your app

You can also use the React Native CLI to generate and run a Release build (e.g. react-native run-android --variant=release).

Connecting to the development server

You can also iterate quickly on a device using the development server. You only have to be on the same Wi-Fi network as your computer. Shake your device to open the Developer menu, then enable Live Reload. Your app will reload whenever your JavaScript code has changed.

Troubleshooting

If you have any issues, ensure that your Mac and device are on the same network and can reach each other. Many open wireless networks with captive portals are configured to prevent devices from reaching other devices on the network. You may use your device's Personal Hotspot feature in this case.

1. Wi-Fi network.

Make sure your laptop and your phone are on the same Wi-Fi network.

2. IP address

Make sure that the build script detected the IP address of your machine correctly (e.g. 10.0.1.123).

Open the Report navigator tab, select the last Build and search for xip.io. The IP address which gets embedded in the app should match your machines IP address plus the domain .xip.io (e.g. 10.0.1.123.xip.io)

3. Network/router configuration

React Native uses the wildcard DNS service xip.io to address your device, as Apple ATS prohibits URLs with IP addresses instead of domain names, and developers' networks are often not set up to resolve local hostnames. Some routers have security features to prevent DNS Servers from resolving to anything in the local IP range.

Now check if you are able to resolve the xip.io address, by running nslookup.

$ nslookup 10.0.1.123.xip.io

If it doesn't resolve your local IP address either the xip.io service is down or more likely your router prevents it.

To still use xip.io behind your router:

configure your phone to use Google DNS (8.8.8.8)

disable the appropriate security feature in your router

Connecting to the development server

You can also iterate quickly on a device by connecting to the development server running on your development machine. There are several ways of accomplishing this, depending on whether you have access to a USB cable or a Wi-Fi network.

Method 1: Using adb reverse (recommended)

You can use this method if your device is running Android 5.0 (Lollipop) or newer, it has USB debugging enabled, and it is connected via USB to your development machine.

Run the following in a command prompt:

$ adb -s <device name> reverse tcp:8081 tcp:8081

To find the device name, run the following adb command:

$ adb devices

You can now enable Live reloading from the Developer menu. Your app will reload whenever your JavaScript code has changed.

Method 2: Connect via Wi-Fi

You can also connect to the development server over Wi-Fi. You'll first need to install the app on your device using a USB cable, but once that has been done you can debug wirelessly by following these instructions. You'll need your development machine's current IP address before proceeding.

Type in your machine's IP address and the port of the local dev server (e.g. 10.0.1.1:8081).

Go back to the Developer menu and select Reload JS.

You can now enable Live reloading from the Developer menu. Your app will reload whenever your JavaScript code has changed.

Building your app for production

You have built a great app using React Native, and you are now itching to release it in the App Store. The process is the same as any other native iOS app, with some additional considerations to take into account.

1. Enable App Transport Security

App Transport Security is a security feature introduced in iOS 9 that rejects all HTTP requests that are not sent over HTTPS. This can result in HTTP traffic being blocked, including the developer React Native server. ATS is disabled for localhost by default in React Native projects in order to make development easier.

You should re-enable ATS prior to building your app for production by removing the localhost entry from the NSExceptionDomains dictionary in your Info.plist file in the ios/ folder. You can also re-enable ATS from within Xcode by opening your target properties under the Info pane and editing the App Transport Security Settings entry.

If your application needs to access HTTP resources on production, see this post to learn how to configure ATS on your project.

2. Configure release scheme

Building an app for distribution in the App Store requires using the Release scheme in Xcode. Apps built for Release will automatically disable the in-app Developer menu, which will prevent your users from inadvertently accessing the menu in production. It will also bundle the JavaScript locally, so you can put the app on a device and test whilst not connected to the computer.

To configure your app to be built using the Release scheme, go to Product → Scheme → Edit Scheme. Select the Run tab in the sidebar, then set the Build Configuration dropdown to Release.

3. Configure app to use static bundle

During the development process, React Native has loaded your JavaScript code dynamically at runtime. For a production build, you want to pre-package the JavaScript bundle and distribute it inside your application. Doing this requires a code change in your code so that it knows to load the static bundle.

In AppDelegate.m, change the default jsCodeLocation to point to the static bundle that is built in Release.

This will now reference the main.jsbundle resource file that is created during the Bundle React Native code and images Build Phase in Xcode.

Note: The static bundle is built every time you target a physical device, even in Debug. If you want to save time, turn off bundle generation in Debug by adding the following to your shell script in the Xcode Build Phase Bundle React Native code and images:

Pro Tip

As your App Bundle grows in size, you may start to see a white screen flash between your splash screen and the display of your root application view. If this is the case, you can add the following code to AppDelegate.m in order to keep your splash screen displayed during the transition.

4. Build app for release

You can now build your app for release by tapping ⌘B or selecting Product → Build from the menu bar. Once built for release, you'll be able to distribute the app to beta testers and submit the app to the App Store.

You can also use the React Native CLI to perform this operation using the option --configuration with the value Release (e.g. react-native run-ios --configuration Release).

Building your app for production

You have built a great app using React Native, and you are now itching to release it in the Play Store. The process is the same as any other native Android app, with some additional considerations to take into account. Follow the guide for generating a signed APK to learn more.