What and why? 👀

For starters, what exactly is Expo? Expo is a bundle of tools created around React Native to help you start an app very fast. It gives you the means to simplify the creation and testing of React Native App. With Expo, there is no need to directly use Xcode or Android Studio. That means you can finally develop for iOS even if you are not a Macbook lover.

What’s more, if you choose Expo, you will never have to touch any native Swift, Objective-C or Kotlin or Java code. This means you can rely on just your Javascript skills for developing a real-feel native app, ready to be used on both iOS and Android! However, sometimes you still need to add some native code. We will go over the steps on how to do that as well!

Setting up the project 💻

You can read all about getting started on this link, here we will do just a quick overview so you can get right into the important stuff. The first step should be downloading the Expo Go app on your phone as well as installing the Expo CLI on your computer:

1npm install --global expo-cli

Then you should enter the following command in the terminal and choose one out of four templates:

1expo init-my-app

After installing the project, you can start the app by entering

1expo start

A QR code will now pop up on the screen, then you can scan the code from within the Expo Go app if you’re using Android, or directly from the phone's camera if you're using iOS. Now you can see all the changes you’ve made within the app right as you make them.

Adding native modules using plugins 📌

Sometimes during your development, you will need to use native modules not directly supported by React Native. Before switching to the bare workflow, you should check if there is a plugin available for the module you need. Expo uses plugins to generate and configure all the native code for a managed project.

If there is a plugin available, you can easily add it to your project following these instructions. First, you need to install the plugin of your choice. After installation finishes, edit the app.config.json or app.json file. Edit the expo key and put in the following code:

2  "expo": {
3    "plugins": ["@config-plugins/name-of-your-plugin"]
4  }

Before being able to fully use the native module, you need to build the application in the development mode using EAS. You can read up more about building later in the article. Now you can start your app with:

1expo start –dev-client

Permissions ☑️

Some native modules require the user to give his permission. With Expo, you don’t have to dig into the native code to handle permissions. It is again enough to just edit the app.config.json file. Here we will be adding this Bluetooth plugin, but the process is the same for any available plugin. For Android, you need to add a new permission field like this

2   "android": {
3      "permissions": ['BLUETOOTH', 'BLUETOOTH_ADMIN'],
4    },

For iOS, you need to do a bit more work.

2"ios": {
3      "bundleIdentifier": 'your.bundle.identifier',
4      "infoPlist:" {
5        "NSBluetoothAlwaysUsageDescription":
6          'Our app uses bluetooth to find, connect and transfer data between different devices',
7      },
8    },

And that's it! Now your app will ask the user for his/hers permission on startup.

Adding native modules with no plugins available 🖇️

Even though by using Expo we try to stay away from native coding, occasionally there is no other way to achieve some functionality.
Up until recently, if you wanted to add native code, you needed to eject Expo altogether. That means that you wouldn't be able to use the Expo Go app anymore, but more importantly, you would need to remove all your plugins and add them to the native code by hand! Luckily, now there is a workaround and that is using Expo's new feature - the bare workflow!

If you want to use custom native code that isn't already in the Expo Go app, you will need to generate the native iOS and Android projects. To do that, first, you need to switch from managed to bare workflow. You do this by running

1expo run:android


1expo run:ios

Using the run commands will initially prebuild your project to generate all of the native code within your project directory. Keep in mind that you need to have both Xcode and Android Studio installed to do this. Now, you can test your native code on simulators, and continue to use the Expo Go for all other testing and development. You can’t access native code while using the Expo Go app, but you can still access and keep all of your plugins.

After adding a plugin to the bare workflow, you need to run expo prebuild so Expo CLI adds required permissions to the Info.plist and AndroidManifest.xml. As before, anytime you add a new plugin, you need to build the app again.

Building the app 🔨

To build the app, we will use EAS Build. EAS Build allows you to build a ready-to-submit binary of your app for the Apple App Store or Google Play Store. First, you will need an Expo Dev account. You can register here.

At the root of your project, you have eas.json, where you can find the four types of builds: dev-ios-simulator, development, preview, and production.

  • Development builds include developer tools, and they are never submitted to an app store.
  • ️Dev-ios-simulator build is used to create the development build for the iOS simulator.
  • Preview builds don't include developer tools, they are intended to be installed by your team and other stakeholders, to test out the app in production-like circumstances.
  • ️Production builds are submitted to the app store, they are meant for release to the general public or as part of a store-facilitated testing process such as TestFlight.

You can change the default value of the bundle identifier in the app.config.js file. By default, the build will be of production type. You can also specify the build type in your command.

1eas build --profile development

After that, you can select the platform for which you want to build or you can skip that step by specifying the platform directly in the command.

1eas build --profile development --platform all

The Android build will start immediately. If you chose iOS, log in to your Apple account.

When the build is over, go to the given link or scan the QR code and install the app. Keep in mind that the app won't run with build types Development and Preview on iOS devices that are not registered on your Apple account.

In the development and preview build, the result for an Android build is the .apk file, while for the production build the result is the .aab file. If you want to change the type of build file, you will need to edit the eas.json file.

2  "build": {
3    "preview": {
4      "android": {
5        "buildType": "apk"
6      }
7    },
8    "preview2": {
9      "android": {
10        "gradleCommand": ":app:assembleRelease"
11      }
12    },
13    "preview3": {
14      "developmentClient": true
15    },
16    "production": {}
17  }

You only need to make a new build if you add new native dependencies, or if you register a new Apple device in your provision profile and you want to run the build on it. 

Conclusion 📝

With Expo's new features, you can finally use it for the whole development process. Adding plugins and native code has never been easier. Since the building process lasts only a few minutes, your clients can now get day-to-day updates on your progress! Other than that, definitely check out the documentation for other commonly used features.

Have fun and stay tuned for more! 📻 😊

Written by
Paula Vulić

Junior React Native Developer

If you like this article, we're sure you'll love these!