Not all listeners are equally private.
A listener on 127.0.0.1 is local-only. It accepts connections from your own machine.
A listener on 0.0.0.0 or * is wider. It means the process is listening on every available network interface.
That may include:
- localhost
- your Wi-Fi address
- your Ethernet address
- a VPN interface
- a Tailscale interface
- a Docker bridge
This is useful when intentional. It is dangerous when accidental.
The mental model
These two listeners are not the same:
127.0.0.1:3000
0.0.0.0:3000
127.0.0.1:3000 means:
Only this machine can knock on door 3000.
0.0.0.0:3000 means:
Listen for knocks on door 3000 from every interface this machine has.
Sometimes tools display this as:
*:3000
That is another way of saying “wildcard address.”
Why it matters
A local admin panel is fine on 127.0.0.1.
The same panel on 0.0.0.0 may be reachable from another device on your network.
That does not automatically mean the whole internet can reach it. Routers, firewalls, NAT, and macOS permissions still matter. But it does mean the process is no longer asking to be local-only.
For development, this often happens when you use flags like:
--host 0.0.0.0
--host
Some tools use those flags to make your dev server reachable from a phone or another computer.
Read the binding
Run:
lsof -nP -iTCP:3000 -sTCP:LISTEN
Look at the NAME column.
You may see:
TCP 127.0.0.1:3000 (LISTEN)
That is loopback-only.
You may also see:
TCP *:3000 (LISTEN)
or:
TCP 0.0.0.0:3000 (LISTEN)
That is wildcard listening.
Safe defaults
For most local development, prefer:
127.0.0.1
localhost
Use wildcard binding only when you need another device to reach your server.
Good reasons:
- Testing a mobile layout on your phone.
- Testing a webhook through a tunnel.
- Letting a teammate on the same network inspect a temporary demo.
- Running a container or VM that needs host access.
Bad reasons:
- You copied a command and do not know why it includes
--host 0.0.0.0. - You are running a database with no password.
- You are exposing a local admin panel.
- You are on public Wi-Fi.
Common examples
Vite local-only:
npm run dev -- --host 127.0.0.1
Vite reachable from the network:
npm run dev -- --host 0.0.0.0
FastAPI local-only:
uvicorn app.main:app --host 127.0.0.1 --port 8000
FastAPI reachable from the network:
uvicorn app.main:app --host 0.0.0.0 --port 8000
The second version is not automatically wrong. It just deserves attention.
Find your LAN address
On macOS, your Wi-Fi IP is often available with:
ipconfig getifaddr en0
If the result is something like:
192.168.1.42
then another device on the same network may be able to try:
http://192.168.1.42:3000
That works only if the app is bound to a reachable interface and the firewall/network allows it.
Security rule
If you see:
0.0.0.0:PORT
*:PORT
ask:
- Why does this need to be reachable beyond my machine?
- Is the service protected?
- Am I on a trusted network?
- Can I bind it to
127.0.0.1instead?