Skip to main content
The expo prebuild command generates native ios/ and android/ directories from your app configuration, enabling you to use native code, libraries, and build tools directly.

Usage

npx expo prebuild [directory] [options]

Arguments

directory
string
Directory of the Expo project. Defaults to the current working directory.

Options

--platform
string
Platforms to generate: ios, android, or all. Default: all. Alias: -p
--clean
boolean
Delete the native folders and regenerate them before applying changes. Ensures a fresh state.
--no-install
boolean
Skip installing npm packages and CocoaPods.

Package Manager Options

--npm
boolean
Use npm to install dependencies. Default when package-lock.json exists.
--yarn
boolean
Use Yarn to install dependencies. Default when yarn.lock exists.
--pnpm
boolean
Use pnpm to install dependencies. Default when pnpm-lock.yaml exists.
--bun
boolean
Use bun to install dependencies. Default when bun.lock or bun.lockb exists.
--template
string
Project template to clone from. Can be:
  • File path to a local tar file
  • npm package name
  • GitHub repository URL
--skip-dependency-update
string
Comma-separated list of packages to preserve versions in package.json. Useful for testing specific versions.

What is Prebuild?

Prebuilding is the process of generating native iOS and Android projects from your Expo app configuration. This is necessary when you need to:
  • Use native modules that require custom native code
  • Modify native build configuration
  • Add native dependencies not available in Expo Go
  • Prepare for building with Xcode or Android Studio
  • Use EAS Build or build locally with expo run

When to Use Prebuild

You Need Prebuild When:

  • Installing a library that requires native code changes
  • Adding custom native modules
  • Modifying native build settings
  • Setting up custom URL schemes or app extensions
  • Configuring native permissions or capabilities
  • Building for production

You Don’t Need Prebuild When:

  • Working with Expo Go
  • All your dependencies are supported by Expo Go
  • Doing JavaScript-only development
  • Using managed workflow exclusively

Examples

Basic Prebuild

Generate both iOS and Android projects:
npx expo prebuild
This creates:
  • ios/ directory with Xcode project
  • android/ directory with Gradle project
  • Installs native dependencies (CocoaPods for iOS)

Generate Specific Platform

iOS only:
npx expo prebuild --platform ios
Android only:
npx expo prebuild --platform android

Clean Prebuild

Delete existing native folders and regenerate:
npx expo prebuild --clean
This is useful when:
  • You’ve made manual changes you want to discard
  • You want to ensure configuration is correctly applied
  • You’re troubleshooting build issues

Skip Installation

Generate native projects without installing dependencies:
npx expo prebuild --no-install

Specify Package Manager

Use a specific package manager:
npx expo prebuild --npm

Custom Template

Use a custom template:
npx expo prebuild --template ./my-custom-template.tar.gz
Or from npm:
npx expo prebuild --template expo-template-bare-minimum

Preserve Package Versions

Keep specific package versions during prebuild:
npx expo prebuild --skip-dependency-update react-native,expo

How It Works

When you run expo prebuild, the CLI:
  1. Reads Configuration - Loads app.json or app.config.js
  2. Validates Dependencies - Checks for native module compatibility
  3. Generates Native Projects - Creates ios/ and android/ directories
  4. Applies Config Plugins - Runs config plugins to modify native files
  5. Installs Dependencies - Runs pod install for iOS
  6. Syncs Configuration - Applies settings from app config to native projects

Generated Files

iOS Directory Structure

ios/
├── Podfile                 # CocoaPods dependencies
├── MyApp.xcworkspace/      # Xcode workspace
├── MyApp.xcodeproj/        # Xcode project
└── MyApp/                  # App source
    ├── AppDelegate.mm      # App lifecycle
    ├── Info.plist          # App configuration
    └── Images.xcassets/    # App icons and assets

Android Directory Structure

android/
├── app/
│   ├── build.gradle        # App-level build config
│   └── src/main/
│       ├── AndroidManifest.xml  # App manifest
│       ├── java/           # Java/Kotlin source
│       └── res/            # Android resources
├── build.gradle            # Project-level build config
├── settings.gradle         # Project settings
└── gradle.properties       # Gradle properties

Config Plugins

Prebuild uses Config Plugins to modify native projects. These plugins run during prebuild to configure native code based on your app.json.

Common Config Plugins

  • expo-camera - Adds camera permissions
  • expo-location - Configures location services
  • expo-notifications - Sets up push notifications
  • expo-splash-screen - Generates splash screens
  • expo-updates - Configures OTA updates

Example Configuration

app.json
{
  "expo": {
    "name": "My App",
    "ios": {
      "bundleIdentifier": "com.mycompany.myapp"
    },
    "android": {
      "package": "com.mycompany.myapp"
    },
    "plugins": [
      [
        "expo-camera",
        {
          "cameraPermission": "Allow $(PRODUCT_NAME) to access your camera."
        }
      ]
    ]
  }
}

Continuous Prebuilding

You can safely run expo prebuild multiple times. The command is idempotent, meaning:
  • Running it again with the same config produces the same result
  • Changes in app.json are applied to native projects
  • Manual native changes are preserved if not in conflict

Best Practice

Use --clean flag when you want to ensure a pristine state:
npx expo prebuild --clean

Manual Native Changes

After prebuilding, you can make manual changes to native code:
  1. Open ios/*.xcworkspace in Xcode
  2. Open android/ in Android Studio
  3. Modify native code, add files, configure settings

Important Notes

  • Manual changes may be overwritten by future prebuilds
  • Use Config Plugins for reproducible native configuration
  • Version control your native directories to track changes
  • Document manual changes for team members

Gitignore Native Directories

You can choose to either commit or ignore native directories: Add to .gitignore:
# Native
ios/
android/
Benefits:
  • Smaller repository size
  • No merge conflicts in native files
  • Easy to regenerate with expo prebuild
  • Enforces declarative configuration

Option 2: Commit Native Directories

Benefits:
  • Full control over native code
  • Can make manual native changes
  • Easier to see what changed
  • No need to rebuild for reviewers

Troubleshooting

CocoaPods Installation Fails (iOS)

Update CocoaPods:
sudo gem install cocoapods
Clean CocoaPods cache:
cd ios
pod deintegrate
pod install

Gradle Build Fails (Android)

Check Java version:
java -version
Ensure you have JDK 17 or newer. Clear Gradle cache:
cd android
./gradlew clean

Config Plugin Errors

Ensure all packages with config plugins are installed:
npx expo install --check

Prebuild Keeps Failing

Try a clean prebuild:
rm -rf ios android node_modules
npm install
npx expo prebuild --clean

Platform Not Supported

iOS prebuild is not supported on Windows. Use:
  • macOS for iOS development
  • EAS Build for cloud building
  • --platform android flag to skip iOS
npx expo prebuild --platform android

Comparing Workflows

WorkflowNative DirectoriesExpo GoCustom Native Code
ManagedNot generated
PrebuildGenerated
BareCommitted
Prebuild enables a hybrid approach: use Expo tooling with custom native code.