Every React Native project starts with the same question: Expo or bare workflow? The short answer: use Expo unless you have a specific reason not to.
September 11, 2024 10 min read
# Expo vs. Bare React Native: When to Choose What
Slug: expo-vs-bare-react-native
Date: 2024-09-11
Tag: Tech Stack
Meta Description: Practical guide to choosing between Expo and bare React Native. When Expo's convenience wins, when bare workflow is necessary, and how to decide for your MVP.
---
Every React Native project starts with the same question: Expo or bare workflow?
The short answer: use Expo unless you have a specific reason not to. The long answer fills the rest of this post.
We've shipped mobile MVPs with both approaches. Expo wins for most startup projects because it removes infrastructure complexity. Bare workflow wins when you need native code access that Expo doesn't support. Knowing which situation you're in saves weeks of development time.
What Expo Actually Is
Expo is a layer on top of React Native that provides:
Managed native code: You don't touch Xcode or Android Studio
Pre-built modules: Camera, file system, push notifications work out of the box
Over-the-air updates: Deploy JavaScript changes without app store review
Build service: Cloud builds for iOS and Android
Development tools: Fast refresh, error overlays, debugging
Think of Expo as "batteries included" React Native. The common features every app needs are already configured.
Expo apps are larger (typically 30-50MB minimum) because they include all Expo modules. For an MVP where download size isn't critical, this trade-off is fine.
You want over-the-air updates
Expo's EAS Update lets you push JavaScript changes without app store review. Fix bugs in minutes instead of days. This is valuable for MVPs iterating quickly.
Your team doesn't have native experience
If nobody on your team has built iOS or Android apps before, Expo eliminates the learning curve. You stay in JavaScript/TypeScript land.
You're validating an idea
For MVPs testing market fit, development speed trumps almost everything else. Expo gets you to users faster.
Choose Bare Workflow When
You need an unsupported native library
Some native libraries don't have Expo equivalents:
Specific payment SDKs with native requirements
Custom video players with DRM
Specialized Bluetooth libraries
Enterprise MDM integrations
If your core feature requires one of these, bare workflow is necessary.
App size is critical
For apps where download size materially affects conversion (emerging markets, very casual users), bare workflow's smaller footprint matters.
You need heavy native customization
Some apps require deep native integration:
Custom camera interfaces
Complex audio processing
Native animations that JavaScript can't achieve
Integration with specific native SDKs
Enterprise security requirements
Some enterprise deployments require specific native security configurations, jailbreak detection implementations, or other low-level controls.
You're building on existing native apps
If you're adding React Native to an existing iOS or Android app (brownfield development), bare workflow is typically required.
The Expo Modules Revolution
Expo's architecture changed significantly with the Expo Modules API. Understanding this matters for the decision.
Old Model: All or Nothing
Previously, Expo was a complete package. You either used the full Expo SDK or you "ejected" to bare React Native.
Ejecting was messy. It created an entire native project you now maintained. Most teams ejected too early, then dealt with complexity they didn't need.
New Model: Modular Adoption
Modern Expo uses a modular approach:
Development builds: Create custom native builds with only the modules you need
EAS Build: Cloud builds without managing Xcode/Android Studio
Config plugins: Modify native configuration from JavaScript
You can use Expo's tooling while adding native modules that aren't in the SDK. The "eject" concept is largely obsolete.
This means: start with Expo, add native modules as needed, only go fully bare if absolutely necessary.
Practical Comparison
Let's compare building the same MVP feature with each approach.
Feature: Camera with Face Detection
With Expo:
typescript
import { Camera, FaceDetector } from 'expo-camera';
function CameraScreen() {
const handleFacesDetected = ({ faces }) => {
if (faces.length > 0) {
// Face detected, proceed with verification
}
};
return (
<Camera
type={Camera.Constants.Type.front}
onFacesDetected={handleFacesDetected}
faceDetectorSettings={{
mode: FaceDetector.FaceDetectorMode.fast,
detectLandmarks: FaceDetector.FaceDetectorLandmarks.all,
}}
>
{/* UI overlay */}
</Camera>
);
}
This is smoother than the old "eject" process. Expo modules continue working; you just have native project access.
Bare to Expo
Less common, but possible:
Add Expo as a dependency
Use Expo modules alongside other native modules
Adopt EAS Build and Update incrementally
The boundaries are more permeable than they used to be.
Our Approach at NextBuild
For mobile MVPs, we default to Expo with this reasoning:
Start with Expo SDK: Use managed modules for standard features
Development builds: Add custom native modules if needed
EAS Build and Update: Cloud builds and OTA updates
Prebuild if necessary: Generate native projects only when required
This approach covers 90% of MVP needs without native project maintenance.
For the 10% that need bare workflow from the start—heavily native features, enterprise requirements, brownfield integration—we scope that appropriately in project planning.
Integration with Our Web Stack
Most startups building mobile apps also need a web presence. Our approach:
This reduces total development effort compared to completely separate mobile and web teams.
Common Mistakes to Avoid
Choosing Bare Workflow Too Early
Teams often choose bare workflow because they "might need" native access. In practice:
They don't need it
Or they could use Expo development builds
Or the feature requirement changes
Start with Expo. Switch if actually necessary.
Underestimating Native Complexity
Teams with only web experience underestimate bare workflow complexity:
iOS certificates and provisioning profiles
Android build variants and signing
Platform-specific debugging
CI/CD for native builds
Budget 2-4 weeks just for infrastructure with bare workflow.
Ignoring App Size Early
Expo's app size penalty matters in some markets. Check with user research:
Users on limited storage devices
Users on slow or metered connections
App store visibility factors
For most markets, the 20-30MB overhead is acceptable.
Not Testing on Real Devices
Both approaches need physical device testing. Expo Go makes this easier, but development builds or bare apps eventually need real device verification:
Permission dialogs behave differently
Camera and sensors need actual hardware
Performance varies from simulators
Plan for device testing from the beginning.
Key Takeaways
The decision is simpler than it appears:
Use Expo when:
Your features are covered by Expo SDK
Development speed is the priority
Your team is JavaScript-focused
You want OTA updates
Use bare workflow when:
You need unsupported native libraries
App size is critical for your market
Enterprise requirements demand specific native controls
You're integrating with existing native apps
For most startups building MVPs, Expo is the right choice. The development speed advantage compounds over the project lifecycle. Save bare workflow for when you specifically need it. For understanding technology trade-offs without engineering background, see Tech Stack for Non-Technical Founders.
---
At NextBuild, we build mobile MVPs with Expo and React Native alongside our Next.js web applications. If you're planning a mobile product and want to move fast with a modern stack, let's discuss your project.
Learn how to create a basic version of your product for your new business.