Expo vs React Native: Understanding the Difference and What Expo Is in React Native

Expo is a framework and tooling layer built on top of React Native that provides a managed native runtime, pre-configured SDK modules, and cloud build services, eliminating the need to maintain native Android and iOS projects until you require custom native code.

The expo/expo repository on GitHub hosts the open-source implementation of the Expo platform. While both technologies enable cross-platform mobile development using JavaScript and React, understanding what Expo is in React Native and how it differs from core React Native is essential for choosing the right development workflow.

What Is Expo in React Native?

Expo is not a replacement for React Native but rather a curated set of tools, services, and native modules that sit on top of it. According to the expo/expo source code, the expo package serves as the single entry point that enables any React Native app to use Expo modules. In the managed workflow, Expo provides a pre-compiled native runtime (the Expo Go client) that contains dozens of native APIs, allowing developers to write pure JavaScript code without touching Android Studio or Xcode.

The framework abstracts away the complexity of native project configuration. As documented in packages/expo/README.md, installing the expo package activates an autolinking system that makes native modules available without manual installation steps.

Key Differences Between Expo and React Native

Native Project Setup and Configuration

React Native (core) requires you to generate and maintain separate Android (android/) and iOS (ios/) native projects using react-native init. Manual linking of native modules and native code changes are common when adding third-party dependencies.

Expo supplies a pre-configured native runtime through the Expo Go client. A plain JavaScript project can run immediately with npx expo start. No native project files are generated until you "eject" to a bare workflow. This distinction is fundamental to the expo vs react native comparison for rapid prototyping.

Access to Native APIs and SDK Modules

React Native provides only a core set of APIs (e.g., basic networking and touch handling). To access additional native functionality like camera or geolocation, you must add third-party native modules, which often require manual installation and native code changes.

Expo includes dozens of Expo SDK modules (e.g., expo-camera, expo-location, expo-notifications) that are automatically linked and work instantly in the managed workflow. These modules are thin wrappers around native code that the Expo runtime already contains, as implemented in the various packages/expo-* directories within the expo/expo repository.

Build, Distribution, and OTA Updates

With plain React Native, you must configure Gradle and Xcode, generate signed binaries manually, and handle over-the-air (OTA) updates with a separate service like Microsoft CodePush.

Expo’s EAS Build service produces signed binaries for you, while EAS Update enables OTA updates without resubmitting to the app stores. This integrated build pipeline represents a significant operational difference in the expo vs react native ecosystem.

Development Workflow and Tooling

React Native development typically requires running react-native run-android or react-native run-ios, with Metro bundling your JavaScript while you manage device/simulator configurations for each platform.

Expo streamlines this with expo start, which generates a QR code you can scan with the Expo Go app on a physical device. Hot reloading works instantly across both platforms without native compilation steps. The templates/expo-template-default/README.md file in the repository demonstrates this minimal setup requirement.

Managed vs. Bare Workflows

Expo offers two distinct modes, whereas React Native only operates in what Expo calls "bare" mode.

Managed Workflow: You write only JavaScript/TypeScript. The native runtime is provided by Expo Go or a custom development client. No android/ or ios/ directories exist in your project. This is the fastest way to build but limits you to Expo SDK modules and supported third-party libraries.

Bare Workflow: You eject to a standard React Native project structure, generating android/ and ios/ directories. You retain full control over native code while still being able to import Expo modules. The packages/expo/scripts/launchPackager.command file in the repository handles Metro bundler integration when developing bare Expo apps in Xcode.

Practical Code Examples

Creating a New Project

Managed Expo (no native code needed):

npx create-expo-app my-app
cd my-app
npx expo start      # opens Metro and displays QR code for Expo Go

Plain React Native:

npx react-native init MyApp
cd MyApp
npx react-native run-android   # or run-ios

Using Expo SDK Modules

The following example uses expo-location, which requires no manual linking in the managed workflow:

import React from 'react';
import { Text, View } from 'react-native';
import * as Location from 'expo-location';

export default function App() {
  const [location, setLocation] = React.useState(null);

  React.useEffect(() => {
    (async () => {
      const { status } = await Location.requestForegroundPermissionsAsync();
      if (status === 'granted') {
        const loc = await Location.getCurrentPositionAsync({});
        setLocation(loc);
      }
    })();
  }, []);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>
        {location ? `Lat: ${location.coords.latitude}` : 'Fetching location…'}
      </Text>
    </View>
  );
}

With plain React Native, you would need to install @react-native-community/geolocation and perform manual native linking steps.

Ejecting from Managed to Bare

When you need custom native code, you can eject while retaining Expo module support:

npx expo eject   # converts to standard React Native project structure

After ejection, you can open the generated android/ and ios/ folders in Android Studio or Xcode while still being able to import * as Camera from 'expo-camera'.

Key Implementation Files in expo/expo

The following source files illustrate how Expo builds its managed runtime and integrates with React Native:

Summary

  • Expo is a React Native framework that adds a managed native runtime, SDK modules, and cloud services, not an alternative to React Native.
  • Managed workflow eliminates native project maintenance until you eject, while bare workflow provides full React Native control with Expo module access.
  • Expo SDK modules (like expo-camera and expo-location) work out-of-the-box without manual linking, unlike most third-party React Native libraries.
  • EAS Build and EAS Update provide integrated CI/CD and OTA update capabilities not included in core React Native.
  • The expo/expo repository contains the autolinking system, native module wrappers, and development tools that enable these workflows.

Frequently Asked Questions

Can I use Expo modules in a plain React Native app?

Yes. You can install the expo package into any existing React Native project (created with react-native init) to enable Expo modules in a bare workflow. According to packages/expo/README.md, this activates the autolinking system, allowing you to import modules like expo-camera without ejecting from a managed project.

What is the Expo Go client?

Expo Go is a pre-compiled native application available on the App Store and Google Play. It contains the entire Expo SDK runtime, allowing you to develop and test managed workflow apps by scanning a QR code from expo start. It bundles many native modules, making the initial download larger than a minimal React Native binary, but it enables instant development without local compilation.

When should I eject from managed to bare workflow?

You should eject when you need functionality that requires custom native code not covered by the Expo SDK, or when you need to modify native project settings (such as complex Android manifest changes or iOS entitlements) that cannot be configured through Expo's app.json configuration. The npx expo eject command generates standard android/ and ios/ directories while preserving your ability to use Expo modules.

Does Expo affect my app's bundle size?

In the managed workflow, your app runs within the Expo Go client or a custom development client, which includes many native modules. This results in a larger binary size compared to a minimal React Native app. However, in production builds using EAS Build, unused native code can be tree-shaken, and you only pay the size cost for modules you actually import. The bare workflow behaves identically to standard React Native regarding bundle size.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →