---
title: Ejecting to Expo’s Bare Workflow – IOS
description: Expo’s managed workflow is so simple, it makes it easy for any beginner to jump right in. Learn more about ejecting to Expo's bare workflow on iOS.
---

[Michael Washburn Jr's Blog ](https://michaelwashburnjr.com/blog)

# [Ejecting to Expo’s Bare Workflow – IOS](https://michaelwashburnjr.com/blog/eject-expo-bare-workflow)

 Written by [Michael Washburn Jr](https://michaelwashburnjr.com/blog/author/michael-washburn-jr) | Dec 18, 2019 11:00:00 AM

I loved learning React Native through Expo. Expo’s managed workflow is so simple and elegant; it makes it easy for any beginner to jump into app development.

## Why would I eject from Expo’s managed workflow?

When building my first app in Expo, I was unable to continue making progress with the managed workflow. I needed to build in-app purchases. An[ in-app purchase library](https://docs.expo.io/versions/latest/sdk/in-app-purchases/) exists for Expo, but you need to eject to the bare workflow to use it.

I tried digging through the documentation, trying to figure out a nice way to get this to work without ejecting, but came up empty handed. I figured, “I’ve been sheltered by Expo for too long, let’s see what React Native is like without it.”

And thus began my journey ejecting into the bare workflow.

## Step 1: Run the Eject Script

The first step in ejecting is to run the eject script. This is as easy as running `expo eject`.

When you run this, you’ll see the following options:

```
? How would you like to eject your app?
  Read more: https://docs.expo.io/versions/latest/expokit/eject/ (Use arrow keys)
❯ Bare: I'd like a bare React Native project.
  ExpoKit: I'll create or log in with an Expo account to use React Native and the Expo SDK.
  Cancel: I'll continue with my current project structure.
```

You’ll want to select the default option, bare.

After this a bunch of stuff will run to setup your ios and android projects and your app startup code for each.

This is your friendly reminder to commit after each step when doing a complex migration like this one.

## Install Cocoapods and Dependencies

Cocoapods is a tool you probably didn’t need while you were still working with Expo’s managed workflow. It’s used to install Swift and Objective-C dependencies on IOS. If you’re not building for iOS, you won’t need to do this part.

[Cocoapods is super easy to install](https://cocoapods.org/).

```
sudo gem install cocoapods
```

After this, you can `cd` into your `ios` folder and run `pod install` to install all of your dependencies for IOS.

## Remove references to the `Expo` package

One of the tradeoffs we make when switching to Expo’s bare workflow is not being able to use some of the modules imported directly from `Expo`. Search for anything being imported from the Expo package like `import { MyPackage } from 'expo'`.

Some of the problem modules for me were:

- Notifications
- AppLoading
- SplashScreen

These can be replaced fairly easily. However, Notifications can be one of the harder modules to migrate away from. I replaced my old notifications implementation with [react-native-push-notifications-ios](https://github.com/react-native-community/react-native-push-notification-ios) and [wrote my own wrapper for the package using React Hooks.](https://gist.github.com/MichaelWashburnJr/8c40dc2a75f5d77aae4def1218ec57a5)

## Reconfigure broken modules

At this point, you should try running your app. To do this, open your IOS project in Xcode. Click the build button at the top. This should run the metro bundler and launch your simulator, or run on your connected device.

Please note that **you won’t be able to use the Expo app to run your app anymore.**

When you run your new app for the first time, I’m guessing you’re going to start hitting a lot of errors. You’ll have to look at which modules are causing errors for you, and determine if you need to reinstall the module or migrate to a new one.

### expo-facebook

One module that I had to re-install when I migrated to Expo’s bare workflow was `expo-facebook`. The proper pod was not installed when I ejected, so I followed [these bare workflow installation instructions](https://github.com/expo/expo/tree/master/packages/expo-facebook#installation-in-bare-react-native-projects).

Basically, I just had to [install react-native-unimodules](https://github.com/unimodules/react-native-unimodules#-installation). Then, I could `expo install expo-facebook`, and do a `pod install` to get it working again.

### expo-constants

I also started receiving `null` from `expoConstants.default.manifest`. This caused a few issues in some more modules I was using. To side-step this issue, I added the following code to my `App.js`:

```
import Constants from 'expo-constants';
import * as manifest from './app.json';
if (!Constants.manifest){
    Constants.manifest = manifest.expo
}
```

Of course, make sure `expo-constants` [is installed first](https://github.com/expo/expo/tree/master/packages/expo-constants).

### expo-sentry

I also had to refactor how I was initializing `expo-sentry` in my app. Previously, I was just calling it when my App.js function was being loaded. Moving my `Sentry.Init` call to the constructor of my main `App` component resolved this.

Ideally, I think it’d be best to do this type of work in a `componentDidMount`, since it’s likely hitting some API during initialization, but I don’t want to wait until my component has mounted to start capturing errors.

## What problems did you have?

This was my experience ejecting my app from Expo’s managed workflow into Expo’s bare workflow. If you had different problems or have questions about the process, **leave a comment below.**

[View full post](https://michaelwashburnjr.com/blog/eject-expo-bare-workflow)

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Michael Washburn Jr"
  },
  "dateModified" : "2021-04-24T00:43:05.265Z",
  "datePublished" : "2019-12-18T11:00:00Z",
  "headline" : "Ejecting to Expo’s Bare Workflow – IOS",
  "image" : {
    "@type" : "ImageObject",
    "height" : 498,
    "url" : "https://f.hubspotusercontent20.net/hubfs/4674423/Imported_Blog_Media/expo-workflow.jpg",
    "width" : 996
  },
  "mainEntityOfPage" : "https://michaelwashburnjr.com/blog/eject-expo-bare-workflow",
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "height" : 60,
      "url" : "/hs/hsstatic/content_shared_assets/static-1.4092/img/default-amp-logo.png",
      "width" : 60
    },
    "name" : "michaelwashburnjr.com"
  }
}
```