Skip to main content

Overview

While Expo provides a comprehensive SDK, sometimes you need custom native code or third-party libraries with native dependencies. Expo’s prebuild workflow makes this possible while maintaining a great developer experience.

Understanding Prebuild

Expo’s prebuild workflow generates the ios and android directories from your app.json configuration:
This creates:
  • ios/ - Xcode project
  • android/ - Android Studio project
Both are gitignored by default and regenerated as needed.
Prebuild is similar to eject but reversible. You can delete the native directories and regenerate them anytime.

When to Use Custom Native Code

  • Adding third-party libraries with native dependencies
  • Implementing features not available in Expo SDK
  • Integrating platform-specific SDKs (payment processors, analytics, etc.)
  • Building custom native modules
  • Modifying native build configuration

Adding Native Libraries

1

Install the library

2

Run prebuild

This automatically:
  • Links the native module
  • Updates CocoaPods (iOS)
  • Updates Gradle dependencies (Android)
3

Rebuild the app

Example: Adding react-native-maps

Then use it:
app/map.tsx

Config Plugins

Config plugins modify the native projects during prebuild without manual editing:
app.json

Common plugins

app.json

Creating Custom Native Modules

Using Expo Modules API

The modern way to create native modules:
1

Create a local Expo module

This creates:
2

Implement iOS module

modules/my-module/ios/MyModule.swift
3

Implement Android module

modules/my-module/android/src/main/java/expo/modules/mymodule/MyModule.kt
4

Use the module

app/index.tsx

Module capabilities

Creating Config Plugins

Config plugins automate native configuration:
plugins/withCustom.js
Use it:
app.json

Modifying Native Code Directly

If you need full control:
1

Run prebuild without gitignore

app.json
2

Modify native files

Edit ios/ and android/ directories directly in Xcode or Android Studio.
3

Commit changes

Once you commit native directories, npx expo prebuild will warn you before overwriting changes. You lose some benefits of the managed workflow.

Development Workflow

With native directories

EAS Build with Custom Native Code

Custom native code works seamlessly with EAS Build:
eas.json
Build:
EAS Build runs npx expo prebuild automatically.

Troubleshooting

For iOS specifically:
  • Check minimum iOS/Android version requirements
  • Verify the library is compatible with React Native version
  • Look for config plugin in library documentation
  • Check for peer dependency warnings
The --clean flag removes and regenerates native directories.

Best Practices

  • Use config plugins: Automate native configuration instead of manual editing
  • Stay in managed workflow: Keep native directories gitignored when possible
  • Document native dependencies: List libraries with native code in README
  • Test on both platforms: Native code behavior can differ
  • Use Expo Modules API: Prefer it over React Native’s legacy bridge
  • Version lock native dependencies: Specify exact versions to avoid breaking changes
  • Clean rebuilds: Run npx expo prebuild --clean when in doubt
  • Check compatibility: Verify libraries work with your Expo SDK version

Migration from Bare Workflow

If you have existing native directories:
1

Backup native changes

2

Remove native directories

3

Add plugins for native changes

Convert manual native modifications to config plugins in app.json.
4

Regenerate with prebuild

5

Test thoroughly