You’re probably in one of two places right now. Either you’ve opened three React Native setup guides and they disagree on half the steps, or you already tried a quick install and hit an Xcode, Android SDK, CocoaPods, or environment variable error before the first screen rendered.
That’s normal. React native set up looks simple from a distance because the app code is JavaScript, but the environment around it isn’t. You’re still wiring together Node.js, package management, Metro, Android tooling, iOS tooling, simulators, emulators, native dependencies, and a build path that won’t fight you later when the app gets more serious.
React Native has been around since March 26, 2015, when Facebook introduced it as a way to build iOS and Android apps from a single JavaScript codebase with native UI rendering instead of WebViews, as covered in Northcoders’ React Native stability overview. That history matters because old tutorials still float around, and many of them teach setup choices that are now legacy habits instead of current best practice.
Why Your React Native Setup Is a Project Foundation
A sloppy setup doesn’t fail immediately. It fails later, when a developer can’t run Android locally, when iOS pods break after one package update, or when a team realizes too late that its tooling choice doesn’t fit the app.
That’s why experienced mobile teams treat setup like part of delivery, not a prelude to “real work.” For small apps, the total path from planning to App Store launch averages 10 to 14 weeks, and neglecting groundwork during the initial setup phase is a primary cause of debugging delays that extend core development sprints and jeopardize launch dates, according to this app launch timeline breakdown.
Sprint 0 is where teams either save time or lose it
If I’m guiding a new team member, I don’t start with commands. I start with decisions:
- What are we building? A prototype, a startup MVP, an internal enterprise app, or a product that needs native SDKs early.
- Who will maintain it? JavaScript-first developers, a mixed mobile team, or a team with dedicated iOS and Android engineers.
- What must work on day one? Push, camera, authentication, background tasks, custom native modules, or just rapid iteration.
Those answers shape the setup more than any install script.
Practical rule: if your team can’t explain why it chose Expo or Bare, the setup decision isn’t finished yet.
Good setup reduces future friction
The right environment does three things early:
| Area | What good setup changes |
|---|---|
| Development flow | Developers can clone, install, run, and debug without tribal knowledge |
| Native integration | iOS and Android dependencies behave predictably when packages are added |
| Performance path | The project starts on the modern architecture instead of carrying legacy baggage |
Teams usually notice setup quality when it’s missing. The app compiles on one laptop, not on another. Android works, iOS doesn’t. A dependency upgrade turns into a half-day of Podfile surgery. That isn’t bad luck. That’s weak project foundation.
Choosing Your Path Expo Or Bare Workflow
The biggest decision in a react native set up happens before the first install. Expo and Bare are not just two ways to create a project. They define how much native complexity your team owns.

When Expo is the better business decision
Expo is the managed path. It removes a lot of native setup burden and gives teams a smoother onboarding experience. That’s why it fits startups, prototypes, internal business apps, and teams that want to validate product ideas before touching native build internals.
The most concrete reason is speed. The Expo-managed workflow offers 85% faster onboarding, often under 10 minutes, and it’s the choice for 70% of new React Native projects. It also reaches a 98% setup success rate on fresh machines, compared with 75% for the bare workflow for beginners, based on RapidNative’s Expo workflow analysis.
Expo is usually the right call when:
- You need fast iteration: product discovery matters more than native customization right now.
- Your team is JavaScript-heavy: you don’t want every developer wrestling with Xcode and Gradle on day one.
- You want opinionated defaults: routing, device APIs, and deployment tooling are easier to adopt.
When Bare is worth the extra complexity
Bare gives you direct control over iOS and Android projects. You own the native directories, native dependency setup, build behavior, and lower-level integration points. That’s the right trade when the app itself demands it.
Choose Bare if your app needs:
- Custom native SDKs or modules that aren’t cleanly handled in a managed path
- Native build customization for enterprise constraints or platform-specific behavior
- Deep performance tuning and direct control over native layers
- A team that already understands mobile toolchains
Bare isn’t “better.” It’s just less abstracted.
The hybrid path that many teams actually need
A lot of teams land in the middle. They want Expo’s developer experience but eventually need native modules, custom builds, or capabilities that go beyond Expo Go.
That’s where confusion usually starts. Developers frequently struggle when integrating native modules into Expo projects without a full ejection, a gap affecting 30% of intermediate developers who need code-level guidance for hybrid workflows using tools like EAS Build, according to the React Native environment setup discussion.
Don’t frame the decision as “Expo forever” versus “Bare forever.” Frame it as “how much native responsibility do we need to own this quarter?”
A quick decision table
| Project type | Better fit | Why |
|---|---|---|
| Startup MVP | Expo | Fast onboarding, easier iteration, less environment overhead |
| Product validation app | Expo | Faster path to testing ideas on devices |
| Enterprise app with custom SDK needs | Bare | Native control usually matters early |
| Team with strong iOS and Android skills | Bare | They can benefit from direct native ownership |
| App starting simple but likely to need native modules | Expo with a hybrid mindset | Keep velocity now, plan for development builds and native extension later |
The wrong move isn’t choosing one path over the other. The wrong move is pretending your requirements are simpler than they are.
The Bare Workflow Environment Configuration
If you choose Bare, treat the environment like production infrastructure on your laptop. The install isn’t hard because any one step is complicated. It’s hard because several tools must agree with each other at the same time.

Start with the versions that reduce surprises
For a modern bare setup, install:
- Node.js LTS v20+
- JDK 17+
- Android Studio
- Xcode 16+ on macOS
- CocoaPods on macOS
- Watchman on macOS
- A package manager you’ll use consistently, either npm or Yarn
The goal isn’t to chase the newest version of everything. The goal is compatibility.
A lot of broken setups come from one developer using a different Java version, another mixing package managers, and a third relying on a machine-wide Ruby setup that CocoaPods doesn’t like.
macOS is still the cleanest route for full iOS and Android work
If your team ships iOS, macOS remains the most straightforward machine for bare setup because it can handle both Apple and Android toolchains in one place. On macOS, expert-level setup includes installing Watchman via Homebrew, which reduces Metro bundler restarts by 40% to 60%, and setting the ANDROID_HOME environment variable, which prevents 50% of “SDK not found” errors during Android builds, as documented in the React Native environment setup guide.
That one environment variable matters more than most beginners expect. If Android Studio is installed but your shell doesn’t know where the SDK lives, builds fail in confusing ways.
Recommended bare setup order
I use this order because it narrows the blast radius when something breaks:
- Install Node.js LTS first and confirm
node -v - Install JDK 17+ before opening Android Studio
- Install Android Studio, SDK components, emulator support, and accept licenses
- Set
ANDROID_HOMEand update your PATH - Install Xcode on macOS and open it once so it finishes its internal setup
- Install CocoaPods
- Install Watchman
- Then initialize the project
That sequence keeps each tool from implicitly relying on something you haven’t finished yet.
Project initialization
For the bare workflow, initialize with:
npx react-native@latest init MyApp
That’s still the practical line most developers expect when starting a bare app. After creation, your first checkpoint isn’t “did the folder generate.” It’s whether both platforms are buildable before any extra package goes in.
A clean first run matters more than a fast first run. Don’t add navigation, state libraries, or analytics until iOS and Android each boot once.
Apple Silicon gotchas on M1 and M2
M1 and M2 Macs are good React Native machines, but they expose version mismatches quickly.
Watch for these issues:
- Ruby and CocoaPods mismatch: if
pod installfails for reasons that don’t point to your app, the Ruby environment is often the culprit. - Old Homebrew formulas or mixed architectures: avoid carrying Intel-era assumptions forward from older setup guides.
- Simulator confusion: after Xcode updates, the selected simulator or command line tools can drift.
What works best is boring discipline. Install current tooling, keep shell configuration simple, and verify each native tool independently before blaming React Native.
For iOS-specific delivery concerns after setup, a focused guide on React Native for iOS is worth keeping close.
Windows and WSL2 caveats
Windows can absolutely handle Android React Native work, but teams often make it harder by splitting the toolchain across Windows and WSL2 without a clear reason.
My advice is simple:
| Scenario | Better approach |
|---|---|
| Android-only local development | Use native Windows tooling directly |
| General JavaScript work plus Android build | Keep Node and Android Studio in a consistent host environment |
| Trying to run the full build stack partly in WSL2 | Avoid it unless your team already knows the edge cases |
The common WSL2 mistake is using Linux shell habits for package work while Android SDK, emulators, and device tooling live on the Windows side. That can work, but it adds path, permission, and file watching friction that a new team member doesn’t need.
First-run verification checklist
Before calling your react native set up complete, verify all of this:
- Node works: package install and Metro start without path issues
- Android works: emulator launches, app installs, and Gradle completes
- iOS works on macOS: simulator boots and pods install cleanly
- Environment variables persist: a new terminal session still sees your SDK paths
- One package manager is chosen: no accidental npm and Yarn mixing in the same app
A bare setup takes more care, but the payoff is control. If your app needs real native ownership, this is the route that won’t box you in later.
The Expo Go Quickstart Environment
Expo is what I recommend when the main risk is product uncertainty, not native complexity. If the team needs to validate a concept, test UX, or ship an early internal build, Expo removes a lot of ceremony.

The fast path that actually feels fast
The Expo-managed workflow is appealing because it skips most of the native toolchain on day one. You don’t need Xcode or Android Studio just to see your app run on a phone.
The setup is straightforward:
- Install Node.js LTS
- Install Expo CLI with
npm install -g @expo/cli, or usenpx - Create the app with
npx create-expo-app@latest MyApp --template blank - Start it with
npx expo start - Scan the QR code with Expo Go on iOS or Android
That workflow is why many teams use Expo first. If you want a practical walkthrough after setup, this React Native Expo tutorial is a useful companion.
Why Expo is usually the best starting point for startups
Expo-managed setup offers 85% faster onboarding, often in under 10 minutes, and gives beginners a 98% success rate on fresh machines versus 75% for the bare workflow, as noted earlier in the linked Expo workflow research. Those numbers match what teams feel in practice. Fewer local dependencies means fewer ways to fail.
For startup work, Expo is strong when you need:
- A demo on real devices quickly
- Simpler onboarding for contractors or new hires
- Predictable defaults for app structure
- An easier path into hosted build tooling
If your product roadmap is still moving, optimize for iteration speed first. You can always take on more native responsibility later.
A visual walkthrough helps if you’re new to the flow:
Where Expo Go stops being enough
Expo Go is excellent for prototyping and day-one app work. It becomes less comfortable when the app needs custom native modules that Expo Go doesn’t include.
That doesn’t mean Expo was the wrong choice. It means the project is moving into a development-build phase. At that point, keep Expo’s tooling advantages where they still help, but stop pretending the app is a pure managed prototype.
Creating And Running Your First Application
Once the environment is ready, the first successful run should be intentionally boring. You want the default app on screen before you add navigation, state management, design systems, or API clients.
Create the app the right way for your path
If you chose Bare, initialize with:
npx react-native@latest init MyApp
If you chose Expo, initialize with:
npx create-expo-app@latest MyApp --template blank
After that, open the project and look at the generated structure before editing anything. New developers often skip this and then struggle later because they don’t know what’s framework code, what’s native project code, and what’s app code.
Here's a simple way to understand:
- Expo app structure keeps you focused on JavaScript and framework conventions
- Bare app structure exposes native project folders immediately because you own them
Run on simulator, emulator, and physical device
For Expo, start the development server with:
npx expo start
Then either scan the QR code with Expo Go or choose a simulator or emulator option if your machine supports it.
For Bare, start Metro in one terminal and then run the platform command from another. Use the iOS simulator on macOS, or an Android emulator from Android Studio. If you prefer a physical device, connect it before launch and make sure the platform is ready for developer testing.
What usually blocks the first launch
- Android device permissions: enable developer mode and USB debugging on the phone
- iOS trust issues: if you’re using real device workflows later, developer signing and trust settings become part of the path
- Emulator not booted: many failed launch attempts are just commands targeting a device that isn’t ready yet
- Metro cache weirdness: if the app hangs on startup after package changes, reset caches before assuming the code is broken
A short first-run checklist
| Check | Why it matters |
|---|---|
| App opens on Android | Confirms SDK, emulator, Gradle, and Metro are aligned |
| App opens on iOS | Confirms Xcode, pods, and simulator setup are healthy |
| Hot reload works | Confirms the local dev loop is usable |
| No extra libraries installed yet | Keeps setup verification clean and easy to debug |
Your first application run is an environment test, not a product milestone.
If the default app boots on both platforms, your foundation is real. Only then should you start layering in app architecture.
Post-Setup Essentials And Debugging
A rendered starter screen doesn’t mean your environment is done. It means the minimum path works. Day-one productivity depends on the tools and habits you add next.

Verify Hermes and stay on the modern path
Recent React Native releases have pushed hard toward the New Architecture, and Hermes belongs in that conversation. The reason to care isn’t trend-chasing. It’s development and runtime behavior.
In the verified data, Hermes integration is tied to stronger startup and execution performance in modern React Native setups, and newer project creation paths are built around the current architecture instead of the old bridge model. In practical terms, don’t start a new app on a legacy mental model if the framework has already moved on.
Your check here is simple:
- Confirm Hermes is enabled in the app config and native project
- Make sure your dependencies are compatible with current architecture expectations
- Avoid old tutorials that assume the legacy bridge is still the default path
Install your debugging muscle early
A good setup includes inspection tools, not just build tools. I still want desktop debugging available early for layout checks, logs, network inspection, and native behavior that browser-style debugging won’t explain well.
This is also where teams should establish a debugging routine. If a build breaks, decide whether the problem lives in JavaScript, Metro, CocoaPods, Gradle, environment variables, or device state before changing five things at once.
For a deeper workflow around isolating those issues, this guide to debugging React Native is worth bookmarking.
Styling bugs are part of setup reality
Most setup tutorials stop at “Hello World,” but production friction often starts with styling. Post-setup, 42% of developers waste over 10 hours per week debugging styling inconsistencies between React Native and web standards, including the lack of native box-shadow or universal gap support, according to this discussion of common styling pitfalls.
That matters because new developers often assume React Native styling behaves like browser CSS. It doesn’t.
The mistakes I’d warn a new team member about first
gapisn’t universal web CSS behavior: support and expectations differ from what many React developers assumebox-shadowisn’t a native drop-in mental model: shadows often need platform-aware handling- Gradients are not built-in the way web developers expect: teams often need a library strategy early
- Complex animations and visual polish need dedicated tooling: don’t expect raw styles alone to carry everything
Most “React Native styling bugs” aren’t bugs. They’re mismatched expectations imported from the web.
Platform-specific troubleshooting habits
For Apple Silicon Macs, check native tooling versions before changing app code. CocoaPods, Xcode command line tools, and simulator state usually deserve suspicion before your component tree does.
For Windows, be strict about where the Android SDK, Node runtime, and shell environment live. Mixed host and WSL2 assumptions create confusing path and watcher issues.
A practical triage sequence helps:
- Reproduce the issue consistently
- Identify whether it’s JavaScript, native build, or device state
- Clear only the relevant cache or build output
- Retry with the smallest possible change
- Only then touch dependency versions
That sounds basic, but it saves hours because it prevents panic-driven setup drift.
Next Steps CI Migration And Staying Current
Once your local environment works, the next risk is inconsistency. One machine succeeds, another fails, and the team starts passing around setup folklore in chat messages. That’s the point where local success has to turn into repeatable build infrastructure.
Put CI and build automation in early
If you’re on Expo and already moving beyond local prototyping, EAS Build is usually the next logical step. It helps teams standardize builds instead of relying on whichever laptop currently has the least broken native toolchain.
If you’re on Bare, the principle is the same even if the tooling differs. Build automation forces the project to declare its assumptions. That’s healthy. It exposes missing environment dependencies and undocumented manual steps before they turn into release-day surprises.
Treat older projects carefully during migration
Modern React Native setup is increasingly shaped by the New Architecture. For teams maintaining older apps, migration shouldn’t be emotional. It should be planned.
Use a high-level checklist:
- Audit dependencies first: old native modules often determine how painful migration will be
- Separate setup debt from app debt: some problems are architecture-related, others are just stale dependencies
- Test build reproducibility before feature work: if the environment isn’t stable, migration gets harder to reason about
- Move incrementally when possible: avoid tying architecture shifts to major product deadlines
The key point is simple. Don’t keep carrying legacy setup assumptions just because the app still compiles.
Staying current without chasing noise
React Native changes fast enough that setup guidance ages badly. The best habit is to prefer current official workflows, verify package compatibility before upgrades, and treat old blog posts with suspicion if they assume deprecated commands or older architecture defaults.
That doesn’t mean upgrading constantly. It means staying informed enough that when you do upgrade, you know whether you’re moving with the framework or against it.
A strong react native set up isn’t one that works only today. It’s one your team can still understand, reproduce, and evolve six months from now.
React Native Coders publishes the kind of guidance teams need after the first install, from Expo and Hermes walkthroughs to debugging, performance, and architecture decisions. If you want practical React Native coverage without the fluff, browse React Native Coders.





















Add Comment