localhost:3000 is port 3000 on your own computer, and it's the default development port for React, Next.js, Nuxt, Ruby on Rails and Grafana. When you open http://localhost:3000, the browser connects to whatever process on this machine is listening on port 3000. If you see "This site can't be reached" or ERR_CONNECTION_REFUSED, nothing is listening there right now.
What runs on port 3000
| Tool | Default on 3000? | Start command |
|---|---|---|
| Next.js | Yes | npm run dev (next dev) |
| React (Create React App) | Yes | npm start |
| Nuxt | Yes | npm run dev (nuxt dev) |
| Ruby on Rails | Yes | bin/rails server |
| Express / Node.js | By convention | node server.js (app.listen(3000)) |
| Grafana | Yes | grafana server or Docker -p 3000:3000 |
| Gitea | Yes | gitea web |
Vite-based React and Vue projects use localhost:5173 instead, and Angular uses localhost:4200.
Fix "localhost:3000 refused to connect"
- Check the server is actually running. Look at the terminal where you ran
npm run dev. If the process exited, the error above the prompt tells you why: a missing dependency, a syntax error or a bad env var. - Check the port it really chose. If 3000 was busy, Next.js and many other dev servers silently move to
3001,3002and so on. The terminal prints the real URL (Local: http://localhost:3001). - Try
127.0.0.1instead oflocalhost. Some Node versions bind only to IPv6::1, or only to IPv4. If one name works and the other doesn't, start the server with an explicit host (--host 127.0.0.1orHOST=0.0.0.0). - Inside Docker? The app must listen on
0.0.0.0inside the container, and you need-p 3000:3000to publish the port to your host.
Find and free a busy port 3000
Error: listen EADDRINUSE: address already in use :::3000 means another process already owns the port.
# macOS / Linux: who is on port 3000?
lsof -i :3000
# kill it
kill -9 $(lsof -ti :3000)
# Windows
netstat -ano | findstr :3000
taskkill /PID <pid> /F
Or leave the old process running and move the new one: PORT=3001 npm start, next dev -p 3001, nuxt dev --port 3001, rails server -p 3001.
Open localhost:3000 from another device
localhost only ever points at the machine you're typing on, so your phone can't open your localhost:3000. On the same network:
- Start the server on all interfaces:
next dev -H 0.0.0.0,HOST=0.0.0.0 npm startorrails server -b 0.0.0.0. - Find your LAN IP (
ipconfig getifaddr en0on macOS,hostname -Ion Linux,ipconfigon Windows). - Open
http://192.168.x.x:3000on the other device. Allow the port through your OS firewall if it's blocked.
Share localhost:3000 publicly
To let a client, a teammate or a mobile device on another network see the app, put a tunnel in front of the port. A tunnel needs no router changes or public IP:
relay connect --name my-app http://localhost:3000
The relay CLI opens an outbound connection and prints a public HTTPS URL that forwards to port 3000. Keep the same --name and the URL stays the same across restarts, which matters for OAuth redirect URIs and anything else you've configured with that URL.
If you need webhooks (Stripe, GitHub, Shopify) to reach a handler on port 3000, use relay forward instead:
relay forward --bucket my-app http://localhost:3000/webhooks
Every webhook sent to the bucket's public URL is delivered to your local handler and logged, so you can inspect it and replay it. See receive webhooks on localhost for the full setup.
