Ports and localhost
💡 Learning Guide: When you run
npm run devand the terminal showshttp://localhost:5173, have you ever wondered: what islocalhost? What does5173represent? Why do you sometimes get anEADDRINUSEerror? This chapter will thoroughly explain these concepts you see every day in development but rarely dig into.
Before we begin, it's recommended to brush up on two foundational topics:
- Networking basics: If you're not clear on IP addresses and HTTP concepts, check out Computer Fundamentals - Network Communication.
- Terminal basics: If you're not familiar with the command line terminal, check out Command Line & Shell Scripts.
0. Introduction: What Exactly Is That localhost:5173 You See Every Day?
$ npm run dev
> vite
准备就绪...GET /index.html),然后把对应的文件内容返回给你。Every developer's daily routine includes this line of output:
➜ Local: http://localhost:5173/But have you ever thought about how many key concepts are packed into this short line:
- http:// → The communication protocol (what language to speak)
- localhost → The target address (who to find)
- :5173 → The port number (which door to knock on after finding the address)
Understand these three things, and you'll be able to figure out 90% of development environment networking issues. Let's break them down one by one.
1. What Is a Port? (IP Is the Building, Port Is the Room Number)
1.1 An Intuitive Analogy
Imagine a server is a building:
- An IP address (e.g.,
192.168.1.100) is the building's street address — it tells you "which building to go to." - A port number (e.g.,
:80) is the room number inside the building — it tells you "which room to enter."
A building can simultaneously have a restaurant (room 80), a cafe (room 443), and an office (room 22). Similarly, a single computer can run a web server, a database, and an SSH service simultaneously, each using a different port.
👇 Try it out: Click the "room numbers" below to simulate connecting to different ports. Notice what happens when a port is "open" (a program is listening) versus "closed."
1.2 Port Number Ranges
A port number is an integer between 0–65535 (65,536 total). These ports are divided into three ranges:
| Range | Values | Purpose | Examples |
|---|---|---|---|
| System Ports | 0 – 1023 | Reserved for standard protocols; ordinary users can't freely use them | 80 (HTTP), 443 (HTTPS), 22 (SSH) |
| Registered Ports | 1024 – 49151 | Registered for common applications | 3306 (MySQL), 5432 (PostgreSQL), 6379 (Redis) |
| Dynamic Ports | 49152 – 65535 | Temporarily assigned by the operating system | When a browser makes a request, the OS randomly assigns a source port |
Why does your dev server like to use 3000, 5173, or 8080? Because they're all in the "registered ports" range — no admin privileges needed to listen on them, and they're less likely to conflict with system services.
1.3 Common Port Numbers in Development
👇 Try it out: Enter a port number or service name to search. Click any row to expand and see usage examples.
80HTTP网页访问(未加密)安全443HTTPS网页访问(加密)安全22SSH安全远程登录注意21FTP文件传输敏感3306MySQLMySQL 数据库敏感5432PostgreSQLPostgreSQL 数据库敏感27017MongoDBMongoDB 数据库敏感6379RedisRedis 缓存敏感3000Node/ReactNode.js / React 开发服务器安全5173ViteVite 开发服务器安全8080通用 HTTPHTTP 备用端口 / 代理安全8000Django/PythonDjango / Python HTTP 服务安全5000FlaskFlask 开发服务器安全4200AngularAngular 开发服务器安全53DNS域名解析注意25SMTP邮件发送注意2. What Is localhost? (Finding Yourself)
2.1 The Core Concept of "Loopback"
localhost is a special domain name that always points to your own computer.
When you type http://localhost:3000 in your browser, here's what happens:
- The browser asks the OS: "What's the IP for
localhost?" - The OS answers directly: "
127.0.0.1" (no need to look up DNS over the network) - The packet is sent to
127.0.0.1, but never actually leaves your machine - The OS "loops back" the packet through the loopback interface
- The program listening on port 3000 receives the request and sends a response
The entire process doesn't go through any network cable, router, or internet connection.
👇 Try it out: Click "Send Request" to observe the complete journey of a data packet. Then click the "alias cards" below to learn about the different ways to write localhost and their differences.
localhost→ 127.0.0.1127.0.0.1→ 127.0.0.1::1→ ::10.0.0.0→ 0.0.0.0/etc/hosts 文件里的映射。浏览器看到 localhost 时,直接解析为 127.0.0.1,不会去问 DNS 服务器。 2.2 localhost vs 127.0.0.1 vs 0.0.0.0
These three concepts are often confused, but they mean entirely different things:
| Notation | Meaning | Who Can Access |
|---|---|---|
localhost / 127.0.0.1 | Loopback address, local machine only | Only your own computer |
0.0.0.0 | Listen on all network interfaces | Local machine + other devices on the LAN |
192.168.x.x | LAN IP | Devices on the local network |
Practical scenarios:
# Only you can access (secure, good for development)
npm run dev -- --host localhost
# Your phone can also access (good for mobile debugging)
npm run dev -- --host 0.0.0.0Many frameworks (like Vite, Next.js) listen on
localhostby default, so even if your phone is on the same WiFi, it can't access your dev server. Want to debug on mobile? Just add the--hostflag.
3. Port Conflicts: The Most Common Dev Environment Issue
3.1 Why Do Conflicts Happen?
One port can only be listened on by one program at a time. It's like one room can only house one family.
If you try to start a second service on the same port, you'll see this classic error:
Error: listen EADDRINUSE :::3000In plain English: "Room 3000 is already occupied — you can't get in!"
Common conflict scenarios:
- The previous dev server wasn't properly shut down and is still running in the background
- Two different projects use the same default port
- Some system service has already taken the port you want
👇 Try it out: Try starting services multiple times in the simulator below. When a port conflict occurs, compare how "direct start" and "smart start" handle it differently.
:5173🟢 运行中EADDRINUSE 错误,说明这个端口已经被占了。要么杀掉旧进程,要么换个端口。 3.2 Troubleshooting and Resolution
When you encounter a port conflict, the troubleshooting steps are very consistent:
macOS / Linux:
# Step 1: Check who is using port 3000
lsof -i :3000
# Step 2: Once you have the PID, force kill it
kill -9 <PID>Windows:
# Step 1: Check who is using port 3000
netstat -ano | findstr :3000
# Step 2: Kill the process
taskkill /PID <PID> /FMany modern frameworks (Vite, Create React App, etc.) will automatically ask "switch to another port?" when they detect a conflict. But understanding the underlying principles helps you troubleshoot those tricky issues that frameworks can't handle.
4. Same-Origin Policy and CORS in Development
4.1 What Is an "Origin"?
Browsers have a security mechanism called the Same-Origin Policy: only when the protocol, domain, and port are all identical, are two URLs considered the "same origin."
| URL A | URL B | Same Origin? | Reason |
|---|---|---|---|
http://localhost:5173 | http://localhost:5173/about | ✅ Same origin | Protocol, domain, port are all the same |
http://localhost:5173 | http://localhost:3000 | ❌ Different origin | Different ports (5173 vs 3000) |
http://localhost:5173 | https://localhost:5173 | ❌ Different origin | Different protocols (http vs https) |
4.2 Why Does Frontend-Backend Separation Always Encounter CORS?
When your project architecture is:
Frontend (Vite) → http://localhost:5173
Backend (Express) → http://localhost:3000The frontend page loads from :5173, then uses fetch('/api/users') to request the API on :3000 — different ports trigger the cross-origin restriction!
Two common solutions:
Option 1: Configure CORS on the backend
// Express backend
app.use(cors({ origin: 'http://localhost:5173' }))Option 2: Configure a proxy on the frontend (recommended)
// vite.config.js
export default {
server: {
proxy: {
'/api': 'http://localhost:3000'
}
}
}How the proxy works: The Vite dev server "forwards" requests on your behalf. The browser thinks it's communicating with :5173 (same origin), while Vite secretly relays the requests to :3000 behind the scenes.
5. Practical Troubleshooting: Three Most Common Issues
👇 Try it out: Select an issue you've encountered, and follow the steps to troubleshoot. Click "Execute" on each step to see the output.
lsof -i :30006. Terminology Reference
| English Term | Chinese Translation | Explanation |
|---|---|---|
| Port | 端口 | A number from 0–65535 used to distinguish different network services on the same machine. Each service "listens" on a port, waiting for client connections. |
| localhost | 本地主机 | A special domain name that always points to the local machine (127.0.0.1). Used to access services running on your own machine without an internet connection. |
| Loopback Interface | 环回接口 | A virtual network interface in the operating system. Packets sent to 127.0.0.1 never leave the machine; they are "looped back" through this interface. |
| EADDRINUSE | 地址已被使用 | An error from Node.js / the OS indicating the port you want to listen on is already occupied by another program. |
| CORS | 跨域资源共享 | A browser security mechanism. When a frontend page tries to request an API from a different origin (different protocol/domain/port), the backend must explicitly grant permission. |
| Same-Origin Policy | 同源策略 | The cornerstone of browser security: only allows free communication between requests with the same protocol, domain, and port, blocking cross-origin data reads. |
| Proxy | 代理 | In a dev environment, a proxy server forwards requests from the browser to the backend, bypassing the browser's same-origin restriction. |
| 0.0.0.0 | 所有接口 | When a service listens on 0.0.0.0, it accepts connections from any network interface (local machine, LAN, etc.). |
| Well-known Ports | 知名端口 | The collective name for ports 0–1023, reserved for standard protocols like HTTP (80), HTTPS (443), SSH (22). |
| PID | 进程 ID | A unique number assigned by the OS to each running program, used to manage and terminate processes. |
| lsof | 列出打开的文件 | A macOS/Linux command used to see which process is using a specific port (lsof -i :port_number). |
| HMR | 热模块替换 | A dev server feature: when you modify code, the browser updates automatically without manual refresh. Works via WebSocket notifications under the hood. |
Summary
Ports and localhost are the most fundamental, most frequently encountered concepts in the development environment:
- Port = A "room number" distinguishing different services on a machine (0–65535)
- localhost = The special "find yourself" address (127.0.0.1), data never leaves your machine
- Port conflict is essentially "one room number can only have one sign"
- CORS is essentially "different ports = different origins," requiring CORS or a proxy to resolve
Remember these four points, and you'll be able to quickly identify the cause of most networking issues in your development environment.