Why adb reverse is needed for accessing a local server from Android
If you’ve ever tried to hit your local Rails server from a physical Android device, you’ve probably run into this: your phone can’t reach localhost:3000. The fix is a simple command, but understanding why it works is worth explaining.
The problem: localhost means different things
When you run rails server on your machine, it binds to localhost:3000. Your browser can reach it because “localhost” on your computer means… your computer.
But when your Android phone tries to hit localhost:3000, it’s looking for a server running on the phone itself. There’s nothing there. The phone’s localhost is the phone, not your development machine.
What adb reverse does
The fix is this:
adb reverse tcp:3000 tcp:3000
This command creates a reverse port forwarding tunnel over USB. It tells the Android device: “When something on you tries to connect to port 3000, forward that traffic through the USB connection to port 3000 on the computer.”
After running this, your Android app can hit http://localhost:3000 and it will actually reach your development server.
Why is it called “reverse”?
ADB has two forwarding directions:
adb forward- traffic from computer goes to deviceadb reverse- traffic from device goes to computer
Since we want the phone to reach our computer’s server, we need “reverse” forwarding. The phone initiates the connection, and it gets tunneled back to the computer.
Alternative: WiFi approach
If you don’t want to use USB, you can expose your server on your local network:
rails server -b 0.0.0.0
Then find your computer’s local IP (something like 192.168.1.42) and hit that from your phone:
http://192.168.1.42:3000
This works, but has downsides: your IP might change, both devices need to be on the same network, and you’re exposing your dev server to the whole network. The USB approach is more reliable for development.
Emulator difference
If you’re using the Android emulator instead of a physical device, you don’t need adb reverse. The emulator has a special IP address 10.0.2.2 that maps to your host machine’s localhost. So your emulator can just hit:
http://10.0.2.2:3000
This is built into the emulator. Physical devices don’t have this mapping, which is why they need the reverse tunnel.
Summary
- Physical Android device can’t reach your computer’s
localhost adb reverse tcp:3000 tcp:3000creates a USB tunnel- After that,
localhost:3000on the phone reaches your computer - Emulators don’t need this because
10.0.2.2already maps to host localhost