localhost vs

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 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.

In a network, each device can be identified by an IP address. The IP address belongs to a virtual network interface. This special interface represents the device itself and is only accessible to programs running on this device.


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:

  1. - the well-known IPv4 address (IP address version 4).
  2. [::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 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 ''

*   Trying
* connect to port 3000 failed: Connection refused

As we learned earlier, localhost stands for, 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
* connect to 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.


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 In this case, localhost will continue to work as well.

By understanding the difference between localhost and, and knowing how to handle potential connection issues, you can ensure a smoother development process.