Lesson 1 of 7 · 30 min

Expo vs Bare React Native: How to Set Up a New Project

Compare Expo and bare React Native workflows and set up a project structure that scales to production.

In this lesson1. Two ways to start2. When Expo fits and when bare fits3. Creating the project4. A folder structure that scales

Two ways to start

Every React Native project starts with a choice between the Expo framework and a bare React Native project. Both produce real native apps that run JavaScript through the React Native runtime. The difference is how much of the native tooling you manage yourself. Expo provides a curated set of libraries, a development client, configuration through app config files and cloud build and submit services. A bare project gives you the android and ios folders directly and leaves every native decision to you.

The official React Native documentation now recommends starting new apps with a framework, and Expo is the common choice. That recommendation is a good default, but you should still understand the trade-offs, because client projects sometimes arrive with constraints. A bank in Mumbai may require a specific native security SDK, or a logistics client in Riyadh may already have a native Android app that you need to extend. Read the current setup guides at reactnative.dev and docs.expo.dev before deciding.

When Expo fits and when bare fits

Expo fits most new product work: consumer apps, internal tools, marketplaces and field service apps. You get faster setup, consistent builds across the team and a large set of maintained modules for the camera, notifications, file system and more. Modern Expo projects can still include custom native code through config plugins and development builds, so choosing Expo no longer means you can never touch native code. That removes the main historical objection.

A bare project makes sense when you are adding React Native screens to an existing native app, when a vendor SDK needs deep native setup that has no config plugin, or when the team already has strong native skills and wants full control of the build. Even then, many Expo libraries can be used in bare projects. Write the decision and its reasons in your project README so future developers understand why the setup looks the way it does.

  • Choose Expo for: new apps, small teams, fast iteration, managed builds
  • Choose bare for: brownfield apps, unusual native SDKs, full build control
  • Either way: use TypeScript, a strict lint setup and pinned dependency versions

Creating the project

The commands below show the general shape of an Expo setup. They are illustrative, so check the official documentation for the current form before you run them. Use the Expo install command when adding native libraries, because it picks versions known to work with your SDK version. Mixing incompatible native library versions is one of the most common causes of mysterious build failures in React Native projects.

Run the app on a physical Android phone and an iPhone or iOS simulator within the first hour. Early device testing catches problems with permissions, fonts and safe areas that a web preview hides. Commit the generated lock file so every developer and every CI job installs the same dependency versions. When you later upgrade the SDK, follow the official upgrade guide step by step and upgrade on a separate branch, testing the main journeys before merging.

bash · illustrative
# Illustrative only. Check docs.expo.dev for current commands.

# Create a new Expo project with TypeScript
npx create-expo-app@latest field-orders
cd field-orders

# Run on a device or emulator during development
npx expo start

# Add a native module the Expo way (picks a compatible version)
npx expo install expo-camera

# Generate native android and ios folders when you need them
npx expo prebuild

# Bare React Native alternative: see reactnative.dev
# for the current community CLI init command.

A folder structure that scales

Organise code by feature rather than by file type once the app grows beyond a few screens. A feature folder such as orders contains its screens, components, hooks, API calls and tests together. Shared items such as the design system, API client and utilities live in their own folders. This makes it easy to find everything related to one area of the app and keeps changes small and reviewable.

Set up environment configuration early. You will need at least development, staging and production API URLs, and possibly different app identifiers so testers can install staging and production side by side. Keep secrets out of the app bundle entirely, because anything shipped in a mobile app can be extracted. At XDQ Labs we add environment profiles, linting, formatting and a basic test command on the first day, because retrofitting them later is always harder.

Key takeaways
  • Expo is a sensible default for most new React Native apps
  • Bare projects suit brownfield apps and unusual native requirements
  • Use the Expo install command to keep native library versions compatible
  • Organise code by feature and set up environments on day one
  • Never ship secrets inside a mobile app bundle
Try it

Create a new Expo project with TypeScript and add a feature folder for one area of your app. Configure separate development and production API URLs using app config. Write a short README section explaining why you chose Expo or bare for this project.

Check your understanding

1. Which situation most clearly favours a bare React Native project?

2. Why use the Expo install command for native libraries?

3. Where should API secrets for third-party services live?

← CourseCourse overviewNext lesson →React Native Navigation and State Management Explained
XDQ xAgents · AI lab for your company
While you sleep, your AI agents keep working.

From USD 49 or INR 2,999 a month. A person approves every step.

Start free, 14 days →See every agent300 credits · no card needed · prices include taxes🚀 Startup? Free landing page for 30 days →Need custom software or a security review? Send a brief →