Skip to main content
Environment Setup

Module Overview

Estimated Time: 1-2 hours | Difficulty: Beginner | Prerequisites: Module 1 completed
Setting up a React Native development environment can be tricky, especially for iOS development. Think of it like setting up a workshop: you need different tools depending on what you are building. iOS development requires Apple’s proprietary tools (Xcode, CocoaPods) that only run on macOS — there is no workaround for this at the local level. Android development is more platform-agnostic, but the toolchain (Android Studio, JDK, SDK, emulator with hardware acceleration) has many moving parts that must all agree on versions. This module walks you through every step on all platforms. What You’ll Learn:
  • Expo vs React Native CLI decision
  • Node.js and package manager setup
  • iOS development setup (macOS only)
  • Android development setup (all platforms)
  • VS Code configuration
  • Troubleshooting common issues

Expo vs React Native CLI

Before setting up, choose your development approach. This is one of the most consequential decisions in a React Native project, and it is not as binary as it once was. Expo has evolved from “the training wheels option” to a production-grade toolchain used by companies like Shopify and Discord. The bare CLI remains necessary for brownfield integrations (adding React Native screens to an existing Swift/Kotlin app) and for teams that need full control over native build configuration.
  • You’re learning React Native
  • Building a new project from scratch
  • Don’t need custom native modules (yet)
  • Want faster development iteration
  • Need to build iOS apps on Windows/Linux
  • Want managed OTA updates

Prerequisites (All Platforms)

1. Install Node.js

React Native requires Node.js 18 or newer. Node is the JavaScript runtime that powers Metro (the bundler), the development server, and all the CLI tooling. It does not run on the device itself — Hermes or JavaScriptCore handles that. Think of Node as the backstage crew: essential during development, invisible in production.

2. Install a Package Manager

npm comes with Node.js. No additional installation needed.

3. Install Git


Expo Setup

Quick Start with Expo

Install Expo Go

Download Expo Go on your physical device:

iOS

Download from App Store

Android

Download from Google Play

Running Your App

Expo Development Builds

For native modules not in Expo Go, create a development build:

iOS Setup (macOS Only)

iOS development requires macOS. Windows and Linux users can use EAS Build for cloud-based iOS builds.

1. Install Xcode

Xcode Requirements:
  • macOS Ventura 13.5 or later (for Xcode 15)
  • ~25GB free disk space
  • Apple ID (free)

2. Install Xcode Command Line Tools

3. Install CocoaPods

CocoaPods is the dependency manager for iOS native dependencies — it is to iOS what Gradle is to Android. Every time you install a React Native library that includes native iOS code (camera, maps, push notifications), CocoaPods links those native modules into your Xcode project. If you skip pod install after adding a library, the JavaScript side will try to call native code that does not exist, resulting in a “module not found” crash at runtime.

4. Install iOS Simulator

Watchman improves file watching performance:

iOS Setup Verification


Android Setup (All Platforms)

1. Install Java Development Kit (JDK)

React Native requires JDK 17. Android builds use Gradle, which compiles your Java/Kotlin native code and packages the JavaScript bundle into an APK or AAB. The JDK version must match what Gradle expects — using JDK 11 or JDK 21 instead of 17 will produce cryptic build failures. This is one of the most common Android setup pitfalls: the version mismatch error messages rarely tell you “wrong JDK version” directly.

2. Install Android Studio

Download Android Studio from developer.android.com/studio During installation, ensure these are selected:
  • Android SDK
  • Android SDK Platform
  • Android Virtual Device (AVD)

3. Configure Android SDK

4. Set Environment Variables

Add to ~/.zshrc or ~/.bashrc:

5. Create Android Virtual Device (AVD)

The Android emulator simulates a physical Android device on your computer. Unlike the iOS Simulator (which runs native ARM code directly on Apple Silicon), the Android emulator actually emulates ARM hardware, which is why hardware acceleration (Hyper-V on Windows, KVM on Linux, Hypervisor.framework on macOS) is critical for performance. Without hardware acceleration, the emulator can be 10-50x slower. A practical tip: choose a recent Pixel device image with Google Play services if you need to test Google Maps, Google Sign-In, or push notifications. System images without Google APIs will not have these services available.

6. Enable Hardware Acceleration

Hardware acceleration is enabled by default on macOS with Apple Silicon or Intel HAXM.

Android Setup Verification


VS Code Setup

Install VS Code

Download from code.visualstudio.com

Essential Extensions

These extensions transform VS Code into a capable React Native IDE. The React Native Tools extension gives you inline debugging, and the Expo Tools extension provides autocomplete for app.json configuration (where a single typo can cause silent build failures).

VS Code Settings

Launch Configuration


Physical Device Setup

iOS Physical Device

Android Physical Device

Wireless Debugging (Android 11+)


Troubleshooting

Common Issues

Clean Build Commands


Environment Verification Script

Create a script to verify your setup:
Run with:

Quick Reference

Essential Commands


Mobile Dev Setup Pitfalls

Common environment pitfalls that waste hours:iOS-specific:
  • Xcode updates frequently break CocoaPods caches. After any Xcode update, run pod deintegrate && pod install --repo-update in your ios/ folder.
  • If you see 'React/RCTBridgeModule.h' file not found, it almost always means CocoaPods failed to link properly. A clean pod install (delete Pods/ and Podfile.lock first) fixes it 95% of the time.
  • Running pod install with the wrong Ruby version can silently install incompatible pod versions. Use the system Ruby or rbenv to pin your Ruby version.
Android-specific:
  • The ANDROID_HOME environment variable must point to the SDK location, not Android Studio itself. On macOS it is ~/Library/Android/sdk, on Windows it is %LOCALAPPDATA%\Android\Sdk. Getting this wrong produces “SDK not found” errors.
  • Gradle daemon processes can hold stale caches. If Android builds fail mysteriously after upgrading a dependency, try cd android && ./gradlew --stop && ./gradlew clean.
  • The Android emulator requires significant RAM (2-4 GB per instance). If your machine has 8 GB total, expect slowdowns when running both an emulator and Metro simultaneously.
Cross-platform:
  • Running npm install and yarn install in the same project creates conflicting lock files (package-lock.json vs yarn.lock). Pick one package manager and stick with it.
  • Metro bundler defaults to port 8081. If another process (like McAfee on Windows) is using that port, Metro fails silently or with a confusing error. Use npx react-native start --port 8082 as a workaround.

Next Steps

Module 3: Project Structure

Learn how to organize your React Native project for scalability and maintainability

Interview Deep-Dive

Strong Answer:
  • They cannot run Xcode or iOS simulators on Windows — Apple restricts those to macOS. But they have three viable options. First, EAS Build runs iOS builds in the cloud on Apple silicon machines. The developer writes code on Windows, pushes to a branch, and EAS compiles the iOS build remotely.
  • Second, for on-device testing during development, they can use Expo Go on a physical iPhone. They run npx expo start on Windows, scan the QR code, and Expo Go loads the JS bundle over the network.
  • Third, for native debugging they can use cloud Mac services (MacStadium, AWS EC2 Mac instances) or pair with a macOS-using teammate for iOS-specific issues.
  • What I would not recommend: Hackintosh setups or assuming “it will work on iOS too” based on Android-only testing. Platform differences in keyboard handling, safe areas, and gesture navigation will surface in production.
Follow-up: The same developer reports that their Android emulator runs at 5fps on their Windows machine. How do you diagnose this?Follow-up Answer:
  • The number one cause is missing hardware acceleration. Check if Hyper-V or HAXM is enabled via systeminfo in PowerShell. If “Virtualization Enabled in Firmware” says No, they need to enable VT-x (Intel) or SVM (AMD) in BIOS.
  • Second: verify the system image architecture. Use x86_64 images on Intel hosts and arm64-v8a on ARM-based Windows. Mismatched architectures force software emulation, which is 10-50x slower.
  • Third: allocate at least 2GB RAM and 2 CPU cores in AVD Manager, and enable GPU acceleration (Hardware GLES 2.0).
  • If all else fails, use a physical Android device via USB. It is faster, shows real-world performance, and avoids emulator configuration entirely.
Strong Answer:
  • CocoaPods is the dependency manager for iOS, analogous to npm for JavaScript. Running pod install reads the Podfile, resolves version constraints, downloads native dependency source code, and generates an Xcode workspace that links everything. React Native itself is a CocoaPod, along with every native module.
  • Debugging failures depends on the error. “CDN: trunk URL could not be downloaded”: run pod repo update. “Specs satisfying dependency were not found”: a version conflict — check Podfile.lock for pins. “No podspec found for library”: the RN library was not properly linked — ensure npx pod-install ran after npm install.
  • The nuclear option: cd ios && rm -rf Pods Podfile.lock build && pod cache clean --all && pod install --repo-update. This clears all cached state and rebuilds from scratch.
  • Critical production practice: commit Podfile.lock to version control. Without it, different team members resolve different dependency versions, causing “works on my machine” failures. Treat it like package-lock.json.
Follow-up: Your CI pipeline fails with “The sandbox is not in sync with the Podfile.lock.” What does this mean?Follow-up Answer:
  • The Xcode project sandbox does not match the committed Podfile.lock. Someone updated a pod locally but CI has a stale Pods/ cache.
  • Fix: ensure CI runs cd ios && pod install after npm ci and before the Xcode build. Do not cache Pods/ without also keying on Podfile.lock.
  • Preventive measure: use pod install --deployment in CI, which fails if Podfile was modified without updating Podfile.lock, catching desync issues early.
Strong Answer:
  • First, check if an Expo config plugin already exists for the SDK. Config plugins modify native files (AndroidManifest, MainApplication, Info.plist) at build time without maintaining native code in your repository.
  • If no plugin exists, write a custom config plugin — a JavaScript function that receives the Expo config and returns modified native configuration. This is the modern replacement for ejecting.
  • If the SDK requires runtime native code, create a local Expo module using expo-modules-core. Write Swift/Kotlin that integrates with the Expo module system while keeping the managed workflow.
  • As a last resort, switch to development builds (npx expo run:android) which gives you the android/ directory while still using Expo’s module system. This is not ejecting — you retain EAS Build and EAS Update support.
Follow-up: The custom config plugin works locally but fails in EAS Build. How do you debug cloud build issues?Follow-up Answer:
  • EAS Build runs in a clean environment, so the failure likely involves environment differences. First, check the EAS Build logs for the exact error (they are available in the Expo dashboard).
  • Common causes: the config plugin references a local file path that does not exist in CI, or it depends on an environment variable not set in EAS secrets. Use eas build --local to reproduce the cloud build environment locally.
  • Add console.log statements in your config plugin — they appear in the build logs. Use the withDangerousMod modifier to inspect the generated native files mid-build and verify your modifications are applied correctly.