Detaching Expo Apps to ExpoKit: Concepts

In this post, you’ll learn what ExpoKit is and how it is used for adding native functionality to Expo apps. You’ll also learn some of its pros and cons. 

In my Easier React Native Development With Expo post, you learned about how Expo makes it easier for beginners to begin creating apps with React Native. You also learned that Expo allows developers to get up and running with developing React Native apps faster because there’s no longer a need to set up Android Studio, Xcode, or other development tools.

  • React Native
    Easier React Native Development With Expo
    Wern Ancheta

But as you have also seen, Expo doesn’t support all of the native features that an app might need. Though the Expo team is always working to support more native functionality, it’s a good idea to learn how to convert an existing Expo project to a standard native project so you can easily transition if the need arises. So, in this two-part series, we’ll take a look at how to do that. 

In this post, you’ll learn what ExpoKit is and when you’re going to need it, as well as which of the Expo platform features are retained and lost once you detach to ExpoKit. 


This tutorial assumes that you’ve already set up your computer for Expo and React Native development. This means you will need either Android Studio or Xcode or both, depending on where you want to deploy. Be sure to check out the Get Started With Expo guide, and also the “Getting Started” guide in the React Native docs under the “Building Projects with Native Code” tab for your specific platform if you haven’t done so already. 

Knowledge of Node.js is helpful but not required.

What Is ExpoKit?

ExpoKit is an Objective-C and Java library that allows you to use the Expo platform within a standard React Native project. When I say “standard React Native project”, I mean one that was created using the react-native init command. 

The downside of detaching to ExpoKit is that you will have to set up the standard native development environment for React Native!

Another downside is that you’re limited to the React and React Native version used by ExpoKit at the time you detach your app. This means that there might be compatibility issues that you will need to resolve if the native module you’re trying to install depends on an earlier version of React or React Native. 

If you think your app is going to need a whole lot of native modules which the built-in React Native and Expo APIs don’t already support, I suggest you avoid using the Expo APIs. That way, you can easily “eject” to a standard React Native project at the time you need to start using custom native modules. 

When to Detach to ExpoKit?

You might want to detach your existing Expo project for any of the following reasons:

  • The API exposed by native features supported by Expo doesn’t cover your use case.
  • You need to use a native functionality that’s not currently supported by the Expo platform. Examples include Bluetooth and background tasks.
  • You want to use specific services. Currently, Expo uses Firebase for real-time data and Sentry for error reporting. If you want to use an alternative service, your only option is to write your own code for communicating to the HTTP API about the services you want to use or to install an existing native module that does the job.
  • You have an existing Continuous Integration setup which doesn’t play well with Expo—for example, if you’re using Fastlane or Bitrise for continuous integration. Expo doesn’t really integrate with those services out of the box, so you’ll have to write your own integration code if you want to use them while still on the Expo platform.

Features Retained When Detaching to ExpoKit

Detaching to ExpoKit means that you will lose some of the features offered by the Expo platform. However, the following essential features are still retained:

  • Expo APIs. You’ll still be able to use Expo APIs such as the Permissions API.
  • Live Reload. Detached Expo apps are still able to use live reload while you’re developing the app. The only difference is that you’ll no longer be able to use the Expo client app. If you’re developing for Android, you can still use your Android device or an emulator such as Genymotion to test the app. If you’re developing for iOS, the app can be run on the simulators you installed in Xcode. You can also run it on your iPhone or iPad, but you need to follow some additional steps which I won’t be covering in this tutorial.

Features You Lose When Detaching to ExpoKit

By detaching to ExpoKit, you will lose the following features:

  • Easy app sharing by means of QR code and Expo Snack. Once you’ve detached to ExpoKit, you’ll notice that you can still share your app via the Expo XDE. It will still generate a QR code, but that code will no longer work when you scan it with the Expo client app.
  • Building standalone apps via Expo’s servers. You can no longer use the exp build command to build the .ipa or .apk files on Expo’s servers. This means that you have to install Android Studio or Xcode (depending on which platform you want to deploy) and build the app locally yourself. Alternatively, you can use Microsoft App Center to build the app if you don’t have a local development environment set up yet. Note that you cannot use commands like react-native run-android or react-native run-ios to run the app, as you would in a standard React Native project. 
  • Expo’s Push Notifications service. Expo no longer manages your push certificates after detaching, so the push notification pipeline needs to be manually managed.

What We’ll Be Creating

To showcase the benefit of detaching to ExpoKit, we’ll be creating an app which needs a native feature that the Expo platform does not currently support. The app will be a location-sharing app. It will mostly run in the background, fetching the user’s current location. It will then send that location via Pusher. We’ll also create a web page showing the user’s current location on a map.

Here’s what the app will look like:

location tracking app

You can find the full source of the project in the tutorial GitHub repo.

Setting Up the App

In the remainder of this post, we’ll focus on getting our app set up. Then, in the next post, we’ll flesh out some of the key code to interact with ExpoKit.

Creating a Pusher App

If you want to use Pusher’s services in your app, you’ll need to create an app in the Pusher dashboard. Once logged in, go to your dashboard, click on Your apps and then Create new app, and enter the name of the app:

create Pusher app

Once the app is created, go to App Settings and check the Enable client events check box. This will allow us to trigger Pusher events directly from the app instead of from a server. Then click on Update to save the changes:

enable client events

You can find the keys under the App keys tab. We will be needing those later, once we connect to the Pusher app.

Creating a Google App

Similarly, we need to create a Google project in order to use the Google Maps API and the Geolocation API. Go to console.developers.google.com and create a new project:

create Google project

Next, go to the project dashboard and click on Enable APIs and Services. Search for Google Maps JavaScript API and Google Maps Geocoding API and enable those.

From the project dashboard, go to Credentials and click on Create Credentials > API Key. Take note of the API key that it generates as we will be using it later.

Creating a New Expo Project

Run the following commands in your working directory:

Now the Expo app is ready to test. Just scan the QR code with your Expo client app for iOS or Android.

Coding the App

Now we’re ready to start coding the app. We’ll start developing as a standard Expo project, and then we’ll detach to ExpoKit when we need to use custom native features.

Generating the Unique Tracking Code

Clear the contents of the App.js file in the root of the project directory and add the following imports:

We’ll also use a custom header component:

In the constructor, set the unique_code to its initial state:

The UI of our app will display this unique code.

Finally, here’s the code for the Header (components/Header.js) component:


This has been the first part of our two-part series on detaching Expo apps to ExpoKit. In this post, you learned the concepts behind ExpoKit and began setting up a project that will use ExpoKit functionality. 

In the next post, we’ll detach the app to ExpoKit and then continue coding it so we can run it on a device.

In the meantime, check out some of our other posts about React Native app development!

  • GraphQL
    Code an App With GraphQL, React Native, and AWS AppSync: The Back-End
    Nader Dabit
  • React Native
    Get Started With React Native Layouts
    Wern Ancheta
  • React Native
    Practical Animation Examples in React Native
    Wern Ancheta
  • Mobile Development
    Tools for React Native Development
    Wern Ancheta

Powered by WPeMatico

Leave a Comment

Scroll to Top