DEV Community

Cover image for 🚀 Fixing One of the Most Annoying React Native Dev Problems: Localhost, Emulator Networking, and API URLs
Shahnoor_Mujawar
Shahnoor_Mujawar

Posted on

🚀 Fixing One of the Most Annoying React Native Dev Problems: Localhost, Emulator Networking, and API URLs

If you’ve built a React Native or Expo app that talks to a backend running on your local machine, you’ve probably hit this problem:

localhost works on iOS simulator
10.0.2.2 works on Android emulator
nothing works on a real device
teammates use staging or remote APIs instead

And suddenly you’re debugging:

network routing
emulator networking
.env file switching
platform-specific base URLs

…instead of debugging your actual app.

This post explains why this happens, what’s really going on under the hood, and how I built a small tool to make development API URLs “just work” — safely.

👉 Tool: rn-dev-url
npm: npm install rn-dev-url

🔍 Why localhost behaves differently in React Native

React Native runs in different environments depending on where the app executes — and each one treats localhost differently.

Understanding this helps a lot.

🟣 iOS Simulator — shares your computer network

The iOS simulator runs on your host machine, so:

http://127.0.0.1:

works fine — because both app + backend share the same network.

Everything feels intuitive here.

🟢 Android Emulator — runs in a virtualized network

The Android emulator runs inside a VM.

Inside that VM:

localhost refers to the emulator itself

not your computer

So Android exposes a special alias:

http://10.0.2.2:

That IP maps back to your host machine.

It makes sense once you know it —
but it’s very unintuitive if you don’t.

🟡 Physical Devices — different network entirely

A real device is:

on your Wi-Fi network
not running inside your machine
not in a simulator
So the only way to reach your machine is via:
http://:

Which may fail if:
router isolation is enabled
firewall blocks access
VPN / hotspot affects routing
So behavior changes again.
Meanwhile… teammates may be using staging APIs

So environments look like this:

Context URL
iOS Simulator 127.0.0.1
Android Emulator 10.0.2.2
Device LAN IP
Another Dev Staging API
CI / Preview Remote API

Same codebase
6 different networking realities

And every context break means…

👉 switching .env files
👉 restarting the packager
👉 changing axios base URLs
👉 explaining networking to teammates

Small problem — high frequency — major friction.

🛠️ So I built a small tool to solve this: rn-dev-url

Instead of juggling device-specific URLs, I wanted:

predictable behavior

production-safe guardrails

no magic or heuristics

explicit fallbacks

zero native dependencies

So I built:

👉 rn-dev-url

A tiny utility that automatically resolves the correct API URL in React Native / Expo development — while never exposing LAN IPs or doing smart detection in production.

⚡ Install
npm install rn-dev-url

or

yarn add rn-dev-url

🔧 How it works

In development, it safely tries:

1️⃣ Android Emulator → 10.0.2.2:
2️⃣ iOS Simulator → 127.0.0.1:
3️⃣ LAN Device → 192.168.x.x: (optional)

Optionally verifies connectivity via:

/health

If nothing is reachable:

👉 it falls back to your remote dev / staging API

🛡 In production — detection is disabled by design

No LAN scanning
No auto-resolution
No environment guessing

✔ prodUrl is required
✔ only production URL is used
✔ zero surprises

This was a deliberate design choice.

🧩 Usage Example
import { getDevApiUrl } from "rn-dev-url";

const apiConfig = await getDevApiUrl(3000, {
prodUrl: "https://api.example.com",
healthPath: "/health",
});

console.log(apiConfig.url);
console.log(apiConfig.source);

Possible outputs:

http://10.0.2.2:3000 android-emulator
http://127.0.0.1:3000 ios-simulator
http://192.168.1.42:3000 lan-device
https://api.example.com prod (fallback)

Then use it with axios / fetch:

const api = axios.create({
baseURL: apiConfig.url,
});

No platform checks
No .env juggling
No emulator-only bugs

🎯 Who this is useful for

This tool helps if you:

✔ run backend locally during development
✔ test on emulator + simulator + device
✔ work in a team with mixed setups
✔ switch between local + staging APIs
✔ care about predictable behavior

It’s especially useful for:

Expo apps

mobile API development

developer onboarding

debugging device-only bugs

🧠 Why I avoided “clever auto-magic”

A lot of tools fail because they:

❌ guess environment behavior
❌ silently switch modes
❌ expose LAN IPs in prod
❌ behave differently per device

Instead, this tool is:

boring
explicit
safety-first
predictable

I’d rather be conservative & trustworthy than “smart”.

🚀 Try it out
npm install rn-dev-url

GitHub repo:
https://github.com/shahnoorgit/rn-dev-url

Medium write-up:
https://medium.com/@shahnoormujawar/i-built-a-tiny-tool-to-fix-one-of-the-most-annoying-react-native-dev-problems-cf411ae3de39

Top comments (0)