What “Project Setup” Means in React Native
Setting up a React Native project is the process of creating a working application folder with the correct dependencies, configuration files, and native build targets (Android and/or iOS). Once created, you should be able to: run the app on a simulator/emulator or physical device, edit JavaScript/TypeScript source files, see changes quickly during development, and produce native builds for testing and release.
React Native projects typically fall into two categories: projects managed by Expo (a managed workflow that abstracts much of the native configuration) and projects created with the React Native Community CLI (often called “bare” or “CLI” projects, where you directly own the android/ and ios/ native folders). Both approaches use React Native, but the app structure and setup steps differ slightly.
Choosing a Setup Path: Expo vs React Native CLI
Expo (Managed Workflow)
Expo is a development platform around React Native that simplifies setup and provides a set of prebuilt native modules. It is a strong choice when you want to start quickly, avoid native configuration early, and rely on Expo’s tooling for running and building apps.
- Pros: fast setup, easy running on devices, less native configuration, good defaults.
- Cons: some native customizations require additional steps (config plugins or “prebuild”), and certain low-level native changes may push you toward a bare workflow.
React Native Community CLI (Bare/CLI Workflow)
The React Native CLI creates a project that includes the native Android and iOS projects from day one. This is a strong choice when you know you will need native code changes, custom native modules, or fine-grained control over build settings.
- Pros: full control of native projects, straightforward integration of native SDKs.
- Cons: more setup steps (especially iOS), more surface area for build issues, more configuration to manage.
Prerequisites You Should Have Installed
The exact prerequisites depend on the workflow and your target platform(s). The items below are common in most setups.
- Listen to the audio with the screen off.
- Earn a certificate upon completion.
- Over 5000 courses for you to explore!
Download the app
Node.js and a Package Manager
React Native uses Node.js to run the Metro bundler and manage JavaScript dependencies. You will also use a package manager to install libraries.
- Node.js: use an active LTS version.
- Package manager: npm (bundled with Node) or Yarn.
Git (Recommended)
Git helps you track changes and collaborate. Even for solo projects, it is useful for reverting mistakes and reviewing diffs.
Android Tooling (If Targeting Android)
For Android development, you typically need Android Studio (which includes the Android SDK and emulator tools). You will also need to configure environment variables so build tools can be found.
- Android Studio installed.
- Android SDK installed (via Android Studio’s SDK Manager).
- An Android emulator created (via AVD Manager) or a physical device with USB debugging enabled.
iOS Tooling (If Targeting iOS)
For iOS development on macOS, you need Xcode and its command line tools. iOS simulators are managed through Xcode.
- Xcode installed.
- Xcode Command Line Tools installed.
- CocoaPods installed (commonly required for native iOS dependencies in CLI projects, and sometimes in Expo prebuild workflows).
Step-by-Step: Create a New Project with Expo
This section walks through creating and running a project using Expo. The commands below assume you are in a terminal and have Node installed.
1) Create the Project
npx create-expo-app MyAppThis creates a new folder named MyApp with a starter template. Expo templates may vary slightly by version, but you will typically see an entry file (often App.js or app/index.js) and configuration files like package.json.
2) Move into the Project Folder and Install Dependencies
cd MyAppMost templates install dependencies during creation. If you ever need to reinstall:
npm install3) Start the Development Server
npm run startThis starts the Expo development server. You can then run the app on:
- An iOS simulator (macOS only).
- An Android emulator.
- A physical device using the Expo Go app (for many projects).
4) Run on Android or iOS
Depending on your environment, you can use the interactive options shown in the terminal. Some setups also provide scripts like:
npm run androidnpm run iosIf you use a physical device, ensure it is on the same network as your development machine, or use a tunnel option if needed.
Step-by-Step: Create a New Project with React Native CLI
This section covers the React Native Community CLI approach. It creates android/ and ios/ folders immediately, which is useful when you need native control.
1) Create the Project
npx react-native init MyAppThis generates a new project with native targets. The template may include TypeScript depending on your chosen options and the current defaults.
2) Install iOS Pods (macOS only)
For iOS, you typically need to install CocoaPods dependencies:
cd MyApp/ios && pod install && cd ..If pod install fails, it is often due to CocoaPods not being installed, Ruby environment issues, or Xcode setup problems.
3) Start Metro
cd MyAppnpm startMetro is the JavaScript bundler that serves your code to the app during development.
4) Run the App
In a separate terminal window:
npm run androidnpm run iosFor Android, make sure an emulator is running or a device is connected. For iOS, Xcode simulators should be available.
Understanding the App Structure (Common Files and Folders)
Once the project is created, the next step is understanding what each file is for. The exact structure differs between Expo and CLI projects, but the concepts are consistent: JavaScript/TypeScript source code, dependency management, bundler configuration, and native platform folders (in bare projects).
package.json
package.json defines your project metadata, scripts, and dependencies. It is the central place to see what libraries are installed and which commands are available.
Key parts to recognize:
- dependencies: libraries required at runtime (React, React Native, navigation libraries, etc.).
- devDependencies: tools used during development (linters, TypeScript, testing tools).
- scripts: shortcuts like start, android, ios, test.
node_modules
This folder contains installed dependencies. You typically do not edit it manually and you do not commit it to Git. If dependencies become corrupted, deleting node_modules and reinstalling is a common troubleshooting step.
App Entry File (App.js / App.tsx or index.js)
React Native needs an entry point that registers the root component. Depending on the template, you may see:
- App.js or App.tsx: a root component exported as default.
- index.js: registers the app and points to App.
In many templates, App is the component you edit first. It is the top-level component that renders the rest of your UI.
app.json / app.config.js (Expo)
Expo projects include configuration that describes your app to the Expo tooling and build services. This can include app name, icons, splash screen, permissions, and platform-specific settings.
Common uses:
- Setting the app display name and slug.
- Defining icons and splash images.
- Declaring permissions and platform configuration.
metro.config.js (Sometimes Present)
Metro is the bundler used by React Native. Some projects include metro.config.js to customize how Metro resolves files, handles assets, or integrates with monorepos.
You might touch this file when:
- Adding support for additional file extensions.
- Configuring monorepo setups.
- Adjusting asset resolution behavior.
babel.config.js
Babel transforms modern JavaScript/TypeScript into code that can run in the React Native environment. You will see presets and plugins here.
You might modify it when:
- Adding a Babel plugin required by a library.
- Configuring module path aliases (sometimes done here, sometimes in TypeScript config).
tsconfig.json (If Using TypeScript)
If your project uses TypeScript, tsconfig.json controls TypeScript compiler options. Even when React Native uses Babel to transpile, TypeScript still uses this file for type checking and editor tooling.
Typical adjustments include:
- Path aliases for cleaner imports.
- Strictness settings for type safety.
Native Folders in CLI Projects: android/ and ios/
If you created a React Native CLI project, you will see android/ and ios/ directories. These are full native projects that can be opened in Android Studio and Xcode.
android/ (Gradle Project)
The android/ folder contains a Gradle-based Android project. Important concepts:
- Gradle files control build configuration, dependencies, and build variants (debug/release).
- AndroidManifest.xml declares app permissions and components.
- Java/Kotlin source files include the application and activity classes that bootstrap React Native.
When you run npm run android, the CLI triggers Gradle to build and install the app on a device/emulator, then connects it to Metro.
ios/ (Xcode Project)
The ios/ folder contains an Xcode project (and often an Xcode workspace when CocoaPods is used). Important concepts:
- Info.plist contains app configuration such as permissions usage descriptions.
- AppDelegate is part of the iOS app lifecycle and initializes the React Native bridge.
- Pods/ and Podfile manage native dependencies via CocoaPods.
When you run npm run ios, the CLI builds the app with Xcode build tools and launches it in the simulator (or a connected device, depending on configuration).
How the App Boots: From Native Entry to JavaScript
Even though you write most of your code in JavaScript/TypeScript, a React Native app still starts as a native app. The native layer loads the JavaScript bundle and renders your React component tree.
Development Mode vs Production Mode
In development, the app usually loads JavaScript from the Metro server running on your machine. This enables fast refresh and quick iteration.
In production (release builds), the JavaScript bundle is packaged with the app. There is no Metro server involved, and debugging tools are more limited unless you add specific instrumentation.
Where Your Root Component Fits
Your root component (often App) is the top of your UI tree. It might render a navigation container, a set of screens, or a single layout. Understanding that everything flows from this root component helps you decide where to place global providers (for example, state management, theming, or localization) later.
Practical Workflow: Running, Editing, and Seeing Changes
1) Start the Bundler First
In most workflows, you start Metro (or Expo’s dev server) and keep it running while you develop.
npm startIf you see port conflicts or bundler issues, stopping the process and restarting is often the first step.
2) Run on a Target Device
Choose at least one target (Android emulator, iOS simulator, or physical device). Running on both platforms regularly helps catch platform-specific issues early.
npm run androidnpm run ios3) Edit the Root Component
Open the project in your editor and locate the root component file (commonly App.js or App.tsx). Make a small change such as editing displayed text. Save the file and observe the app update.
If changes do not appear:
- Confirm the bundler is running and the device can reach it.
- Reload the app from the developer menu.
- Clear Metro cache if needed.
4) Use the Developer Menu
React Native provides a developer menu with tools like reload, enabling/disabling fast refresh, and debugging options. Access methods vary by platform and environment (simulator/emulator shortcuts or device gestures).
Organizing Your Source Code: A Practical Starting Structure
New projects often start with everything in App.js, but you will quickly want a structure that scales. There is no single correct structure, but a simple, practical approach is to group by feature or by type. Below is a common “by type” structure that is easy for beginners to navigate.
MyApp/ src/ screens/ components/ navigation/ assets/ utils/ hooks/ App.tsxHow to use these folders:
- screens/: top-level screen components (for example, HomeScreen, SettingsScreen).
- components/: reusable UI pieces (buttons, cards, headers).
- navigation/: navigators and route definitions.
- assets/: images, fonts, and other static files.
- utils/: helper functions (formatting, validation).
- hooks/: custom hooks for shared logic.
If you prefer “by feature,” you might create folders like src/features/auth, src/features/profile, each containing its own components, screens, and logic. The key is consistency and keeping imports predictable.
Step-by-Step: Add a New Screen File and Render It
This exercise helps you verify you understand the structure and how files connect.
1) Create a screens Folder and a Screen Component
Create src/screens/HomeScreen.tsx (or .js if not using TypeScript) with a simple component:
import React from 'react'; import { View, Text } from 'react-native'; export function HomeScreen() { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>Home Screen</Text> </View> ); }2) Import and Render It from App
Update App.tsx (or App.js) to render the screen:
import React from 'react'; import { HomeScreen } from './src/screens/HomeScreen'; export default function App() { return <HomeScreen />; }This confirms your bundler resolves files correctly and that your project structure is working as expected.
Understanding Configuration and Environment Files
.gitignore
.gitignore lists files and folders that should not be committed to version control, such as node_modules, build outputs, and local environment files. Ensure it includes platform build folders and temporary artifacts commonly generated by React Native tooling.
.env Files (When You Add Them)
Many apps eventually need environment-specific values (API base URLs, feature flags). React Native does not automatically load .env files without additional tooling. If you decide to use environment files later, treat them as configuration inputs and avoid committing secrets.
Troubleshooting Setup Issues (Practical Checks)
Problem: Android Build Fails
Common checks:
- Open Android Studio and confirm the SDK is installed.
- Confirm an emulator is running or a device is connected and authorized.
- Check that Gradle can download dependencies (network/proxy issues can break builds).
- Try cleaning the build (in CLI projects) and rebuilding.
Problem: iOS Build Fails (CLI Projects)
Common checks:
- Run pod install in the ios folder after adding native dependencies.
- Open the .xcworkspace (not .xcodeproj) when CocoaPods is used.
- Confirm Xcode command line tools are selected correctly.
Problem: Metro Bundler Issues
Common checks:
- Stop Metro and restart it.
- Clear cache if you suspect stale bundling.
- Ensure no other process is using the same port.
What to Expect as the Project Grows
As you add libraries and features, you will see new files and configuration appear. Examples include:
- Additional native configuration in android/ and ios/ (CLI projects or Expo prebuild).
- More scripts in package.json for building, testing, and linting.
- New folders under src/ as you separate screens, components, and logic.
Keeping a mental model of the app structure helps you debug issues faster: if something is a runtime UI issue, you likely look in src/; if it is a build or permission issue, you likely look in android/ or ios/ (or Expo config); if it is a dependency issue, you check package.json and the lockfile.