AI tools

localhost Won't Open — Why "Connection Refused" and How to Fix It

Illustration: the localhost door is shut because no one's inside

You start a project, open localhost:3000 in the browser — and there it is: "This site can't be reached" or ERR_CONNECTION_REFUSED. First thought, usually: "great, I broke the internet" or "I'm hopeless."

Relax. The internet has nothing to do with it, and 9 times out of 10 it's one of three trivial causes. First let's get what that message means — then we'll walk the causes top to bottom, starting with the most common.

What "connection refused" means

localhost is your own computer. Not a site on the internet — an address meaning "right here, to me" (the same as 127.0.0.1). More in the breakdown on what localhost is.

And localhost:3000 means "knock on my door number 3000." That door is a port. "Connection refused" means exactly one thing: you knocked, and no one's behind the door. Not "broken," but "no one home to answer." Next: three reasons the door is empty.

Cause 1. The server isn't running

The most common one — it's almost always this.

The browser doesn't produce the page itself — your program (the server) serves it, and you have to start it and leave it running. If you never ran the start command, closed the terminal, or the program crashed with an error — nobody's behind the door, hence the refusal.

  • How to check. Look at the terminal where you started the project. See a line like Local: http://localhost:3000 or ready — the server's alive. See a command prompt or a red error — it isn't.
  • How to fix. Run the start command again (usually npm run dev, npm start, or whatever the project's instructions say). Don't close the terminal — while it's open, the server lives. If an error appears on startup, read it: the problem is in the code, not the browser.

Cause 2. The wrong port

The server is running, but you're knocking on the wrong door.

The project might run on 3000 while you opened 8080 out of habit. Or vice versa. Nothing's at the address you tried — refused again.

  • How to check. Take the address from the terminal, not from memory. On startup the server prints exactly which port it's on: http://localhost:5173, :8000, :3000 — different tools, different ports.
  • How to fix. Open the exact address the terminal showed. Just copy it from there. Sounds trivial, but this is what trips people up most.

Cause 3. The port is taken by another process

Sometimes it's the reverse: the server won't start because the door it needs is already occupied.

If you ran the project earlier and closed the window without stopping it properly, the old process can hang around still holding the port. The new start complains: port already in use (EADDRINUSE).

  • How to check. On startup the terminal shows an error with "address already in use" or "port 3000 is already in use."
  • How to fix. Two paths. The easy one — start the project on a different port (many tools offer it themselves: "port taken, use 3001?" — say yes). The clean one — find and kill the stuck process: on macOS and Linux that's lsof -i :3000 to see who's holding the port, and kill <number> to stop it. On Windows it's easiest to restart or close the extra terminal.

If you've been through all three and the door is still empty — it's almost certainly the first: the server isn't actually running, or it crashed. Go back to the terminal and read what it's telling you.

Are localhost and 127.0.0.1 the same?

Essentially yes. Both mean "this same computer." localhost is a name; 127.0.0.1 is the numeric address it points to. Sometimes it helps to try 127.0.0.1:3000 instead of localhost:3000: if the first opens and the second doesn't, the snag is in local name settings — but the server itself is definitely running.

Why does one port work and another doesn't?

Because each port has its own program "sitting" on it. localhost:3000 answers only if something is running on 3000; localhost:8080 will be empty if nothing's there. It's not a failure — just different doors. And it's nothing like a 500 error, where the server answered but crashed inside, or a failing deploy, where the problem is already on the production server, not yours.

Learn vibe coding — don’t just read about it

Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.

Open the app
KODiQ Bot

KODiQ's AI editor. Writes about vibe coding and AI tools in plain language — every day.

All articles →