localhost vs 127.0.0.1
Every web developer is familiar with localhost
. It's what you see when you run npm run dev
or similar commands to start a local HTTP server. You might also know that 127.0.0.1
is the IP address of localhost. But what's the difference, and why might you encounter Connection refused
when trying to reach your localhost by IP? This post will shed light on these questions.
127.0.0.1
In a network, each device can be identified by an IP address. The IP address 127.0.0.1
belongs to a virtual network interface. This special interface represents the device itself and is only accessible to programs running on this device.
localhost
localhost
is a hostname, which is a human-friendly representation of a device in a network.
Like any other hostname or domain, this text should be resolved into an IP address. When you open any domain in a browser, the browser retrieves one or more IP addresses associated with that domain.
localhost
typically corresponds to two IP addresses:
127.0.0.1
- the well-known IPv4 address (IP address version 4).[::1]
- the newer IPv6 address (IP address version 6).
Connection refused
You might encounter this issue when testing API, for instance.
Let's delve into why http://localhost:3000
works perfectly in the browser, but http://127.0.0.1:3000
doesn't. To illustrate, start web app in the console:
$ npm run dev
Nuxt 3.7.4 with Nitro 2.6.3
➜ Local: http://localhost:3000/
➜ Network: use --host to expose
Make request with curl
in the console:
$ curl -v 'http://127.0.0.1:3000/'
* Trying 127.0.0.1:3000...
* connect to 127.0.0.1 port 3000 failed: Connection refused
...
As we learned earlier, localhost
stands for 127.0.0.1
, but direct request fails. This happens because the dev
server is bound to the IPv6 address [::1]
. Make the same request, but to the IPv6 address:
$ curl -v 'http://[::1]:3000/'
* Trying [::1]:3000...
* Connected to ::1 (::1) port 3000 (#0)
There you have it. Finally, let's see what happens when we use the hostname:
$ curl -v 'http://localhost:3000/'
curl -v 'http://localhost:3000/'
* Trying 127.0.0.1:3000...
* connect to 127.0.0.1 port 3000 failed: Connection refused
* Trying [::1]:3000...
* Connected to localhost (::1) port 3000 (#0)
localhost
is resolved into two addresses, and curl
tries both.
Solution
In light of this, there are two potential solutions. The first is to consistently use localhost
wherever your dev server's address is required, such as in testing tools, scripts, and so on.
The second solution is to configure your web application to start the dev server on 127.0.0.1
. In this case, localhost will continue to work as well.
By understanding the difference between localhost and 127.0.0.1, and knowing how to handle potential connection issues, you can ensure a smoother development process.