Lesson 4 of 7 · 8 min

Wildcard listeners deserve attention

0.0.0.0:3000 or *:3000 means the process is listening on all interfaces, not only loopback. Whether other devices can reach it depends on firewall, network, and app settings.

What you'll learn

  • The mental model
  • Why it matters
  • Read the binding

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:

  1. Why does this need to be reachable beyond my machine?
  2. Is the service protected?
  3. Am I on a trusted network?
  4. Can I bind it to 127.0.0.1 instead?