127.0.0.1 — the loopback that never leaves the box
127.0.0.1 is the loopback address. It always means "this machine, right here." Packets sent to it never touch the network — they loop straight back inside the kernel. The whole 127.0.0.0/8 range (16 million addresses) is reserved for loopback, though only 127.0.0.1 is conventionally used.
localhost is just a hostname mapped to 127.0.0.1 via /etc/hosts. When your dev server prints "running at http://localhost:5173", it's binding to that loopback — only programs on the same machine can connect.
0.0.0.0 — bind to everything
0.0.0.0 is not an address you connect to. It's a special binding address that means "accept connections on any interface this machine has." When a server listens on 0.0.0.0:3000, it accepts traffic via:
- Loopback (127.0.0.1)
- Your LAN IP (192.168.1.42)
- Tailscale IP (100.64.x.x)
- Any other interface
Versus binding to 127.0.0.1:3000, which only accepts loopback connections — invisible from any other device.
Why this matters constantly
Most dev servers default to one or the other for safety. Vite defaults to localhost-only. FastAPI defaults to localhost-only. If you want to test from a phone or another machine on the LAN, you need to flip the binding to 0.0.0.0 — and accept that anyone else on that network can hit your dev server too.