# Existing React Native apps

## Overview of using Expo with existing React Native apps

Learn how to use Expo tools and services with existing React Native apps.

If you have a React Native app that doesn't use any Expo tools, you might be wondering what Expo can provide for you, why you might want to use Expo tools and services, and how to get started.
**All tools and services provided by Expo work great in any React Native app**.
You can use [EAS](/eas) to get quickly set up with a professional CI/CD workflow for building, reviewing, deploying, and updating your apps. [Expo CLI](/more/expo-cli/) provides the best command-line experience for working with React Native. The [Expo SDK](/versions/latest/) is an extended standard library for React Native. It gives developers high-quality, well-maintained native libraries that use consistent API conventions to make them easier to learn and use.
If you've ever written a native module for React Native, you'll be surprised how much easier it is to build and maintain modules with the idiomatic Swift and Kotlin DSL provided by the [Expo Modules API](/modules/overview/).
There's so much more to explore, and the links below will help you to explore the options available to you.
## Incremental adoption steps
Below are four suggested phases of incremental adoption. These phases generally progress from quick changes to improve developer experience, to more significant workflow and codebase optimizations.
Only the first phase &mdash; prerequisites &mdash; is required by other phases. After following its instructions, you can skip to the tools and services that are most relevant to your goals in adopting Expo.
### Prerequisites
These first steps are required to later adopt Expo tools and services:
  }
  href="/bare/installing-expo-modules"
/>
  }
  href="/bare/using-expo-cli/"
/>
### Quick wins
The following helps improving development experience and requires configuration:
  }
  Icon={BookOpen02Icon}
  href="/bare/install-dev-builds-in-bare/"
/>
### New workflows
Once your app has `expo` package installed, you can submit your app to app stores with a single command or update configure `expo-updates` library to manage remote updates to you app's code:
  }
  href="/bare/installing-updates/"
/>
### New mindsets
The following helps with your project's long term maintainability, native code maintenance, and easier upgrades:
## Common questions
Note: How long will it take to adopt Expo in my existing React Native project?
---
Adopting Expo doesn't have to be done in one step. You can start with the _quick wins_ and then move on to more complex parts. You can also pick and choose which features you want to adopt based on what is most helpful for your project.
---
Note: What will I gain from using Expo in my React Native app?
---
Adopting Expo tools in your existing React Native app can help you develop faster with the [Expo SDK](/versions/latest/), streamline native code maintenance and upgrades with [CNG](/workflow/continuous-native-generation/), deploy faster with [EAS Update](/eas-update/introduction/), and more.
---
Note: Who uses Expo?
---
Expo is used by top companies worldwide that serve millions of end users. For more information, see our [Expo showcase](https://expo.dev/customers).
---
Note: What impact will adopting Expo have on my app's size?
---
The `expo` package has a small footprint since it only includes a minimal set of modules required in every app with autolinking infrastructure and other Expo SDK libraries that are built-in. For more information on how to determine the actual size of your app, see [Understanding app size](/distribution/app-size/).
---
Note: Why did React Native recommend using Expo?
---
Most React Native developers solve common problems when building an app, such as implementing navigation, accessing Native APIs, upgrading to new versions, and more. This requires using a specific set of tools and libraries to build and maintain your app &mdash; which means you are creating your own framework.
Expo solves these problems by providing a set of primitives and helping you (the developer) to focus on building your app. It also offers tools to iterate faster in development. For more information, see [Why React Native recommends using a framework](https://reactnative.dev/blog/2024/06/25/use-a-framework-to-build-react-native-apps).
---
Note: Do I have to get rid of my native projects to use Expo?
---
By default, Expo projects created with `create-expo-app` use [Continuous Native Generation (CNG)](/workflow/continuous-native-generation/) and do not contain **android** and **ios** native directories. If you incrementally adopt Expo in your existing React Native app, you don't have to remove these directories. You can use `npx expo run:[android|ios]` as an alternative to commands offered by `@react-native-community/cli` to compile your app locally and keep the configuration of your native projects.
---
Note: I use CodePush. Can I continue using it with Expo?
---
CodePush will be retired in March 2025 and is incompatible with React Native's New Architecture, so, in the long run, we recommend switching to EAS Update to manage remote updates to your app's code. However, you can start using Expo tools in your CodePush enabled app today, including the Expo SDK, Expo CLI, EAS Build, and more.
---
Note: Do I have to build with EAS?
---
[Expo Application Services (EAS)](/eas/) are deeply integrated cloud services for Expo and React Native apps that provide tools to build, test, and deploy your app.
Although we recommend using EAS for a smooth collaboration with your teammates and fast distribution, you can compile your app locally, on your CI, or any other way you prefer.
---
Note: Can I install third-party native libraries in my code?
---
Yes, you can install and use third-party libraries that require native projects (**android** and **ios**) configuration or provides a [config plugin](/config-plugins/introduction/) with [development builds](/workflow/overview/#development-builds). See [Using Third-Party libraries](/workflow/using-libraries/#third-party-libraries) for more information.
---
Note: I use React Navigation. Do I have to use Expo Router?
---
You can continue using any navigation library in your project. However, we recommend using Expo Router for all the benefits [described here](/router/introduction).
---


## Install Expo modules in an existing React Native project

Learn how to prepare your existing React Native project to install and use any Expo module.

To use Expo modules in your app, you will need to install and configure the `expo` package.
The `expo` package has a small footprint; it includes only a minimal set of packages that are needed in nearly every app and the module and autolinking infrastructure that other Expo SDK packages are built with. Once the `expo` package is installed and configured in your project, you can use `npx expo install` to add any other Expo module from the SDK.
Depending on how you [initialized the project](/bare/overview/), there are two ways you can install the Expo modules: [automatically](#automatic-installation) or [manually](#manual-installation).
## Automatic installation
To install and use Expo modules, the easiest way to get up and running is with the `install-expo-modules` command.
<InstallSection
  packageName="expo"
  cmd={[
    '# Install and configure the expo package automatically',
    '$ npx install-expo-modules@latest',
  ]}
  hideBareInstructions
/>
- <YesIcon small /> **When the command succeeds**, you will be able to add any Expo module in your
  app! Proceed to [Usage](#usage) for more information.
- <NoIcon small /> **If the command fails**, follow the manual installation instructions. Updating
  code programmatically can be tricky, and if your project deviates significantly from a default
  React Native project, then you need to perform manual installation and adapt the instructions here
  to your codebase.
## Manual installation
The following instructions apply to installing the latest version of Expo modules in React Native 0.81. For previous versions, check the [native upgrade helper](/bare/upgrade) to see how these files are customized.
<InstallSection packageName="expo" cmd={['$ npm install expo']} hideBareInstructions />
Once installation is complete, apply the changes from the following diffs to configure Expo modules in your project. This is expected to take about five minutes, and you may need to adapt it slightly depending on how customized your project is.
### Configuration for Android
<DiffBlock source="/static/diffs/expo-android.diff" />
### Configuration for iOS
<DiffBlock source="/static/diffs/expo-ios.diff" />
Optionally, you can also add additional delegate methods to your **AppDelegate.swift**. Some libraries may require them, so unless you have a good reason to leave them out, it is recommended to add them. [See delegate methods in AppDelegate.swift](https://github.com/expo/expo/blob/sdk-54/templates/expo-template-bare-minimum/ios/HelloWorld/AppDelegate.swift#L24-L42).
Save all of your changes and update your iOS Deployment Target in Xcode to `iOS 15.1`:
- Open **your-project-name.xcworkspace** in Xcode, select your project in the left sidebar.
- Select **Targets** > **your-project-name** > **Build Settings** > **iOS Deployment Target** and set it to `iOS 15.1`.
The last step is to install the project's CocoaPods again to pull in Expo modules that are detected by `use_expo_modules!` directive that we added to the **Podfile**:
<InstallSection
  packageName="expo"
  cmd={[
    '# Install pods',
    '$ npx pod-install',
    '',
    '# Alternatively, the run command will install them for you',
    '$ npx expo run:ios',
  ]}
  hideBareInstructions
/>
### Configure Expo CLI for bundling on Android and iOS
We recommend using Expo CLI and related tooling configurations to bundle your app JavaScript code and assets. This adds support for using the `"main"` field in **package.json** to use [Expo Router](/router/introduction/) library. Not using Expo CLI for bundling may result in unexpected behavior. [Learn more about Expo CLI](/bare/using-expo-cli/).
Note: Use babel-preset-expo in your babel.config.js
---
  <DiffBlock source="/static/diffs/babel-config.diff" />
---
Note: Extend expo/metro-config in your metro.config.js
---
  <DiffBlock source="/static/diffs/metro-config.diff" />
---
Note: Configure Android project to bundle with Expo CLI
---
  <DiffBlock source="/static/diffs/expo-cli-android.diff" />
---
Note: Configure iOS project to bundle with Expo CLI
---
Replace the shell script under **Build Phases** > **Bundle React Native code and images** in Xcode with the following:
```sh /bin/sh
if [[ -f "$PODS_ROOT/../.xcode.env" ]]; then
  source "$PODS_ROOT/../.xcode.env"
fi
if [[ -f "$PODS_ROOT/../.xcode.env.local" ]]; then
  source "$PODS_ROOT/../.xcode.env.local"
fi