iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Expo vs Bare CLI

Choosing between Expo (managed workflow) and the bare React Native CLI. The trade-offs, and a flow to upgrade between them.

React Native — Expo vs CLI

EXAMPLE
# ===== Two front doors =====
# Expo:
#   - Hides Xcode / Android Studio for the start
#   - OTA updates via EAS Update
#   - Pre-built native modules (camera, location, notifications, ...)
#   - Free + paid services (build, submit, update)
#   - Best DX for solo + small teams
#
# React Native CLI (bare):
#   - You manage Xcode / Android Studio + native code
#   - Use any native lib
#   - Custom build configs
#   - More work, more control

# ===== Start with Expo =====
npx create-expo-app my-app
cd my-app
npx expo start
# Scan QR with Expo Go (dev client) — instant on-device preview.

# ===== Bare CLI start =====
npx react-native init MyApp
cd MyApp
npx react-native run-ios
npx react-native run-android
# Requires Xcode + Android Studio.

# ===== Decision tree =====
# Will the app need a NATIVE module not in Expo SDK?
#   - No  -> Expo
#   - Yes -> Expo (with config plugins / custom dev client) OR bare CLI
#
# Need custom Android / iOS native code?
#   - No  -> Expo
#   - Yes -> Expo prebuild OR bare CLI
#
# Want zero ops + OTA updates?
#   - Yes -> Expo
#   - Mostly -> CodePush + bare CLI

# ===== Expo with custom native code (the modern path) =====
# 'prebuild' generates the ios/android folders so you can edit native code:
npx expo prebuild
# After this, you can run via expo OR via Xcode / Android Studio.
# config plugins keep your native customisations declarative in app.json.

# ===== Migrating Expo -> bare CLI (last resort) =====
npx expo prebuild        # generate ios/android
# Then commit; treat as bare CLI from here.
# You lose OTA-managed services unless you add EAS Update separately.

# ===== Build + submit =====
# Expo: eas build + eas submit (cloud builds)
#   npx eas build -p ios
#   npx eas submit -p ios
# Bare CLI: build via Xcode / Android Studio (or fastlane).

# ===== Costs =====
# Expo: free tier generous; paid tiers for build + updates volumes
# Bare CLI: 'free' but your time on native config + builds is not

# ===== Patterns to internalise =====
# - Default to Expo in 2026 unless you have a SPECIFIC native blocker
# - Use prebuild + config plugins to keep native code declarative
# - EAS for builds + submits + OTA updates
# - Pin Expo SDK versions; major upgrades require care

# ===== Pitfalls =====
# - Going bare CLI to 'be safer' and discovering native build pain
# - Sticking with Expo Go after needing a custom dev client
# - Using libraries without checking Expo support
# - Mixing iOS Pod versions with Expo SDK expectations

Why it matters

Default to Expo in 2026. Use prebuild + config plugins when you need native code. Reach for bare CLI only for specific native blockers. The DX gap between Expo and CLI is real; pay for EAS instead of paying yourself in native debugging time.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
# Expo (recommended for most apps)
npx create-expo-app@latest my-app
cd my-app && npx expo start
# Bare CLI (full native control)
npx @react-native-community/cli init MyApp
Try it Yourself »

Exercise

Create a new Expo app.

npx create- -app@latest my-app

Test yourself

Q1. For most apps the recommended path is…
Q2. Expo Go is…
Q3. EAS Build is…

Discussion

Loading…