portless
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePortless
Portless
Replace port numbers with stable, named .localhost URLs. For humans and agents.
用稳定的带名称.localhost URL替代端口号。面向开发人员和AI Agent。
Why portless
为什么选择portless
- Port conflicts — when two projects default to the same port
EADDRINUSE - Memorizing ports — which app is on 3001 vs 8080?
- Refreshing shows the wrong app — stop one server, start another on the same port, stale tab shows wrong content
- Monorepo multiplier — every problem scales with each service in the repo
- Agents test the wrong port — AI agents guess or hardcode the wrong port
- Cookie/storage clashes — cookies on bleed across apps; localStorage lost when ports shift
localhost - Hardcoded ports in config — CORS allowlists, OAuth redirects, files break when ports change
.env - Sharing URLs with teammates — "what port is that on?" becomes a Slack question
- Browser history is useless — history is a mix of unrelated projects
localhost:3000
- 端口冲突——当两个项目默认使用同一端口时出现错误
EADDRINUSE - 记忆端口繁琐——记不清哪个应用在3001端口,哪个在8080端口
- 刷新显示错误应用——停止一个服务器后,在同一端口启动另一个,旧标签页会显示错误内容
- Monorepo场景问题放大——仓库中每个服务都会遇到上述问题,影响范围扩大
- AI Agent测试错误端口——AI Agent会猜测或硬编码错误的端口
- Cookie/存储冲突——上的Cookie会在不同应用间串用;端口变更时localStorage数据丢失
localhost - 配置中硬编码端口——CORS允许列表、OAuth重定向、文件会因端口变更而失效
.env - 与同事共享URL麻烦——“那个应用在哪个端口?”成了Slack上的常见问题
- 浏览器历史记录无用——的历史记录混杂了多个无关项目
localhost:3000
Installation
安装
portless is a global CLI tool. Do NOT add it as a project dependency (no or in a project). Do NOT use .
npm install portlesspnpm add portlessnpxInstall globally:
bash
npm install -g portlessportless是一款全局CLI工具。请勿将其作为项目依赖安装(不要在项目中执行或)。请勿使用。
npm install portlesspnpm add portlessnpx全局安装:
bash
npm install -g portlessQuick Start
快速开始
bash
undefinedbash
undefinedInstall globally
全局安装
npm install -g portless
npm install -g portless
Start the proxy (once, requires sudo for port 80)
启动代理(仅需一次,端口80需要sudo权限)
sudo portless proxy
sudo portless proxy
Run your app
运行你的应用
portless myapp next dev
portless myapp next dev
When run directly in a terminal (TTY), portless can auto-start the proxy (prompts for sudo once). Via package scripts, start the proxy manually first.
在终端(TTY)中直接运行时,portless可以自动启动代理(仅提示一次输入sudo权限)。通过package脚本运行时,请先手动启动代理。Integration Patterns
集成模式
package.json scripts
package.json 脚本
json
{
"scripts": {
"dev": "portless myapp next dev"
}
}Start the proxy once (), then run / as usual.
sudo portless proxypnpm devnpm run devjson
{
"scripts": {
"dev": "portless myapp next dev"
}
}先启动一次代理(),然后像往常一样运行 / 。
sudo portless proxypnpm devnpm run devMulti-app setups with subdomains
带子域名的多应用配置
bash
portless myapp next dev # http://myapp.localhost
portless api.myapp pnpm start # http://api.myapp.localhost
portless docs.myapp next dev # http://docs.myapp.localhostbash
portless myapp next dev # http://myapp.localhost
portless api.myapp pnpm start # http://api.myapp.localhost
portless docs.myapp next dev # http://docs.myapp.localhostBypassing portless
绕过portless
Set or to run the command directly without the proxy:
PORTLESS=0PORTLESS=skipbash
PORTLESS=0 pnpm dev # Bypasses proxy, uses default port设置或即可直接运行命令,不经过代理:
PORTLESS=0PORTLESS=skipbash
PORTLESS=0 pnpm dev # 绕过代理,使用默认端口How It Works
工作原理
- starts an HTTP reverse proxy on port 80 (configurable with
sudo portless proxy)--port - assigns a random free port (4000-4999) via the
portless <name> <cmd>env var and registers the app with the proxyPORT - The browser hits on the proxy port; the proxy forwards to the app's assigned port
http://<name>.localhost
.localhost127.0.0.1/etc/hostsMost frameworks (Next.js, Vite, Express, etc.) respect the env var automatically.
PORT- 会在80端口启动一个HTTP反向代理(可通过
sudo portless proxy配置端口)--port - 会通过
portless <name> <cmd>环境变量分配一个随机空闲端口(4000-4999),并将应用注册到代理PORT - 浏览器访问代理端口上的,代理会将请求转发到应用分配的端口
http://<name>.localhost
.localhost127.0.0.1/etc/hosts大多数框架(Next.js、Vite、Express等)会自动识别环境变量。
PORTCLI Reference
CLI 参考
| Command | Description |
|---|---|
| Run app at |
| Show active routes |
| Start the proxy daemon on port 80 |
| Start the proxy on a custom port |
| Stop the proxy daemon |
| Show help |
| Show version |
| 命令 | 描述 |
|---|---|
| 在 |
| 显示当前活跃的路由 |
| 在80端口启动代理守护进程 |
| 在自定义端口启动代理守护进程 |
| 停止代理守护进程 |
| 显示帮助信息 |
| 显示版本号 |
Troubleshooting
故障排查
Proxy not running
代理未运行
If reports the proxy is not running:
portless <name> <cmd>bash
sudo portless proxyIn a TTY, portless offers to start it automatically. In non-interactive contexts (CI, package scripts), start it manually first.
如果提示代理未运行:
portless <name> <cmd>bash
sudo portless proxy在TTY环境中,portless会自动提示启动代理。在非交互式环境(CI、package脚本)中,请先手动启动代理。
Port 80 already in use
端口80已被占用
Another process (e.g. Apache, nginx) is bound to port 80. Either stop it first, or use a different port:
bash
portless proxy --port 8080 # No sudo needed for ports >= 1024其他进程(如Apache、nginx)已绑定80端口。可以先停止该进程,或者使用其他端口:
bash
portless proxy --port 8080 # 端口>=1024时无需sudo权限Framework not respecting PORT
框架不识别PORT变量
Some frameworks need explicit configuration to use the env var. Examples:
PORT- Webpack Dev Server: use
--port $PORT - Custom servers: read and listen on it
process.env.PORT
部分框架需要显式配置才能使用环境变量。示例:
PORT- Webpack Dev Server:使用
--port $PORT - 自定义服务器:读取并在该端口监听
process.env.PORT
Permission errors
权限错误
The proxy requires because port 80 is a privileged port (< 1024). Either run with or use an unprivileged port:
sudosudobash
sudo portless proxy # Port 80, requires sudo
portless proxy --port 8080 # Port 8080, no sudo needed
sudo portless proxy stop # Stop requires sudo if started with sudo代理需要权限,因为80端口是特权端口(<1024)。要么使用运行,要么使用非特权端口:
sudosudobash
sudo portless proxy # 80端口,需要sudo权限
portless proxy --port 8080 # 8080端口,无需sudo权限
sudo portless proxy stop # 如果用sudo启动的代理,停止时也需要sudoRequirements
系统要求
- Node.js 20+
- macOS or Linux
- Node.js 20+
- macOS 或 Linux