AniUI Academy

Expo vs. Bare React Native

The two on-ramps into React Native development — Expo's managed toolchain versus the bare React Native CLI — and when each one actually earns its trade-offs.

8 min read

Before you write a single line of a real app, you make one structural decision that shapes everything else about how you build and ship it: Expo's managed toolchain, or the bare React Native CLI. Both produce a real React Native app — same components, same hooks, same JSX. What differs is how much of the native project you touch directly, and how much is handled for you.

Two on-ramps, one underlying framework

It's easy to mistake Expo for a separate framework from React Native. It isn't — Expo is a toolchain and set of libraries built on top of React Native. Every Expo app is a React Native app underneath. The choice isn't "React Native or Expo," it's "how much of the native plumbing do I want to manage myself."

Expo (managed toolchain)

Owns the native build process for you — no local Xcode/Android Studio project to hand-maintain. Ships EAS Build for cloud-built binaries, a large library of pre-built Expo modules (camera, location, notifications, and more), and config plugins that let many native customizations be declared in JavaScript/JSON config rather than native code.

Bare React Native CLI

Generates real ios/ and android/ native project folders that you own outright. Full, unrestricted access to native code and any native library, at the cost of owning native build configuration, native dependency upgrades, and platform-specific setup yourself.

What Expo actually gives you

Starting a project with Expo means you get a working app almost immediately without opening a native IDE. Under the hood, Expo provides:

  • A managed native layer. Instead of editing native project files yourself for common needs, many native capabilities are added through Expo modules — packages that already wrap the native code for you — and config plugins, which let you customize native behavior (like adding a permission string, or an icon) through configuration rather than hand-editing native code.
  • EAS Build, Expo's cloud build service, which can produce real iOS and Android binaries without a local Mac or Android Studio setup being strictly required for every build.
  • A faster iteration loop for most day-to-day feature work, because you spend your time in JavaScript/TypeScript rather than native project configuration.

This is why Expo has become the mainstream default recommendation for most new React Native apps: the majority of what apps actually need — camera access, push notifications, secure storage, and dozens of other common capabilities — already has a maintained Expo module, so you rarely need to touch native code at all.

What bare React Native gives you instead

The bare CLI workflow generates the native ios/ and android/ project folders directly into your project and lets you open them in Xcode or Android Studio like any native app. Nothing is hidden or generated on your behalf at build time — what's in those folders is the native project.

That access is the whole point: if you need to add a native SDK that requires custom native code with no existing Expo module or config plugin for it, bare workflow (or dropping into Expo's own path for custom native code) is where that work actually happens. The cost is real, too — you're now responsible for native dependency versions, native build settings, and generally more moving parts that a managed toolchain would otherwise handle for you.

So which one do you reach for?

For the overwhelming majority of apps today, Expo is the sensible starting point — including apps that eventually need a small amount of custom native code, since Expo has its own supported path for adding native code when a project's needs grow past what config plugins and existing modules cover. Reaching straight for bare React Native CLI makes the most sense when you already know, up front, that the app depends heavily on native code that has no Expo module and isn't a good fit for a config plugin — for example, deep integration with a legacy native SDK that expects to be wired up by hand in Xcode or Android Studio.

The honest framing: this isn't "beginners use Expo, professionals use bare RN." Plenty of production apps, including ones with real native requirements, run on Expo precisely because it removes native build busywork without limiting what's actually achievable. The decision is about how much native-project ownership a specific project actually needs, not about skill level.

What to remember

  • Expo is a toolchain built on top of React Native, not a separate framework — every Expo app is a React Native app.
  • Expo manages native builds for you (including cloud builds via EAS Build) and covers most native needs through Expo modules and config plugins.
  • Bare React Native CLI gives you direct, unrestricted access to the native ios/ and android/ projects, at the cost of owning more native setup yourself.
  • Expo is the mainstream default for most apps today; bare RN (or Expo's own native-code path) earns its place when a project needs custom native code no existing module covers.
  • The choice is about how much native-project ownership a project needs, not a beginner-vs-professional split.

Check yourself

3 questions · pass 3/3 to unlock Project Structure and the Entry Point

up to 50
  1. 1.What is the main practical trade-off of starting a project with the bare React Native CLI instead of Expo?

  2. 2.Why has Expo become the mainstream, recommended default starting point for most new React Native apps today?

  3. 3.A team needs to add a highly specialized native SDK that has no existing Expo module or config plugin, requiring custom native code changes no config plugin exposes. What does this scenario call for?

3 left to answer