Expo vs React Native CLI
The managed React Native experience vs bare metal. Expo removed most reasons to eject. Most, not all.
The short answer
Expo over React Native CLI for most cases. Expo is the default choice for React Native in 2026.
- Pick Expo if starting a new React Native project, want the best DX, or don't have dedicated native developers. This is most teams
- Pick React Native CLI if need deep native customization, have native developers on the team, or use modules that don't work with Expo
- Also consider: Flutter is the main alternative. Different language (Dart) but excellent DX and performance.
— Nice Pick, opinionated tool recommendations
Expo Grew Up
Old Expo was limited. No native modules, weird build system, you'd eventually eject and lose everything.
New Expo is different. Development builds replace the old managed workflow. EAS Build compiles native code in the cloud. Config plugins let you modify native projects without ejecting. The restrictions that made people avoid Expo are mostly gone.
Where CLI Still Wins
Some native modules still require bare React Native. Complex Bluetooth integrations, custom native UI components, or apps that need to modify Xcode/Gradle settings that config plugins don't cover.
Also, if your team has strong iOS/Android native developers, they might prefer working directly with the native projects.
The DX Gap
Expo's developer experience is miles ahead. npx create-expo-app, hot reload that actually works, Expo Router for navigation, EAS Submit for app store deployment.
Bare React Native means managing Xcode projects, Gradle files, CocoaPods, manual linking. It's the same DX gap as Create React App vs manual webpack config.
Performance & Bundle Size: The 10% Myth
Let's kill the FUD: Expo apps are not 10% slower. Real benchmarks show a 2-3% overhead from the Hermes engine and Metro bundler, which is imperceptible in 95% of apps. The real performance killer? Bloated JavaScript bundles. Expo's managed workflow optimizes tree-shaking and lazy loading out of the box, often yielding smaller APKs than a bare CLI project with careless dependencies. CLI advocates will point to native code execution for heavy computation, but unless you're building a video editor or a 3D game, Expo's performance is identical. The tradeoff is real for GPU-intensive tasks—use CLI if you need raw Metal/Vulkan access. For 99% of apps, Expo wins with smaller bundles and zero configuration.
EAS Pricing & Cloud Builds: The Real Cost
EAS Build is not free, but it's cheap: $29/month for 500 build minutes, which covers most indie teams. Compare that to the hidden costs of maintaining your own CI—macOS runners, signing certificates, and hours of debugging. EAS Submit automates App Store and Play Store uploads, saving you 2-3 hours per release. The 'free tier' (30 builds/month) is generous for prototyping. Critics complain about vendor lock-in, but EAS uses open-source tools (Turtle, Fastlane) under the hood. You can self-host, but why? The cost of your time debugging a failed build on Bitrise or GitHub Actions far exceeds EAS's monthly fee. Expo's pricing is transparent; CLI's hidden costs are not.
Migration & Eject: The 'Prebuild' Escape Hatch
Expo's 'prebuild' (formerly eject) is not a trap—it's a surgical scalpel. Unlike the old 'eject' that dumped everything, prebuild generates native projects on-demand, allowing you to add custom native code without losing Expo's tooling. You can run npx expo prebuild to get iOS and Android folders, modify them, and still use expo run:ios/android. The catch: once you touch native code, you're responsible for updates. But Expo's modular architecture means you can 'prebuild' only what you need. CLI purists claim you lose over-the-air updates after prebuild—false. Expo's OTA still works with custom native code via expo-dev-client. The real risk is if you heavily modify native files and then try to upgrade Expo SDK—it's possible but messy. For most teams, prebuild is a one-time, reversible operation that gives you native flexibility without abandoning Expo's ecosystem.
Quick Comparison
| Factor | Expo | React Native CLI |
|---|---|---|
| Setup Time | Minutes | Hours |
| Native Module Access | Most (via config plugins) | Full |
| OTA Updates | Built-in (EAS Update) | CodePush or manual |
| Build System | EAS Build (cloud) | Local Xcode/Gradle |
| File-Based Routing | Expo Router | React Navigation (manual) |
| Native Customization | Config plugins | Direct access |
| CI/CD | EAS (managed) | DIY (Fastlane etc.) |
The Verdict
Use Expo if: You're starting a new React Native project, want the best DX, or don't have dedicated native developers. This is most teams.
Use React Native CLI if: You need deep native customization, have native developers on the team, or use modules that don't work with Expo.
Consider: Flutter is the main alternative. Different language (Dart) but excellent DX and performance.
Expo vs React Native CLI: FAQ
Is Expo or React Native CLI better?
Expo is the Nice Pick. Expo is the default choice for React Native in 2026. EAS Build handles native compilation, Expo Router gives you file-based routing, and most native modules work through the config plugin system. Bare React Native CLI is for edge cases only.
When should you use Expo?
You're starting a new React Native project, want the best DX, or don't have dedicated native developers. This is most teams.
When should you use React Native CLI?
You need deep native customization, have native developers on the team, or use modules that don't work with Expo.
What's the main difference between Expo and React Native CLI?
The managed React Native experience vs bare metal. Expo removed most reasons to eject. Most, not all.
How do Expo and React Native CLI compare on setup time?
Expo: Minutes. React Native CLI: Hours. Expo wins here.
Are there alternatives to consider beyond Expo and React Native CLI?
Flutter is the main alternative. Different language (Dart) but excellent DX and performance.
Expo is the default choice for React Native in 2026. EAS Build handles native compilation, Expo Router gives you file-based routing, and most native modules work through the config plugin system. Bare React Native CLI is for edge cases only.
Related Comparisons
Disagree? nice@nicepick.dev