portless

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Portless

Portless

Replace port numbers with stable, named .localhost URLs. For humans and agents.
用稳定的带名称.localhost URL替代端口号。面向开发人员和AI Agent。

Why portless

为什么选择portless

  • Port conflicts
    EADDRINUSE
    when two projects default to the same port
  • 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
    localhost
    bleed across apps; localStorage lost when ports shift
  • Hardcoded ports in config — CORS allowlists, OAuth redirects,
    .env
    files break when ports change
  • Sharing URLs with teammates — "what port is that on?" becomes a Slack question
  • Browser history is useless
    localhost:3000
    history is a mix of unrelated projects
  • 端口冲突——当两个项目默认使用同一端口时出现
    EADDRINUSE
    错误
  • 记忆端口繁琐——记不清哪个应用在3001端口,哪个在8080端口
  • 刷新显示错误应用——停止一个服务器后,在同一端口启动另一个,旧标签页会显示错误内容
  • Monorepo场景问题放大——仓库中每个服务都会遇到上述问题,影响范围扩大
  • AI Agent测试错误端口——AI Agent会猜测或硬编码错误的端口
  • Cookie/存储冲突——
    localhost
    上的Cookie会在不同应用间串用;端口变更时localStorage数据丢失
  • 配置中硬编码端口——CORS允许列表、OAuth重定向、
    .env
    文件会因端口变更而失效
  • 与同事共享URL麻烦——“那个应用在哪个端口?”成了Slack上的常见问题
  • 浏览器历史记录无用——
    localhost:3000
    的历史记录混杂了多个无关项目

Installation

安装

portless is a global CLI tool. Do NOT add it as a project dependency (no
npm install portless
or
pnpm add portless
in a project). Do NOT use
npx
.
Install globally:
bash
npm install -g portless
portless是一款全局CLI工具。请勿将其作为项目依赖安装(不要在项目中执行
npm install portless
pnpm add portless
)。请勿使用
npx
全局安装:
bash
npm install -g portless

Quick Start

快速开始

bash
undefined
bash
undefined

Install 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 (
sudo portless proxy
), then run
pnpm dev
/
npm run dev
as usual.
json
{
  "scripts": {
    "dev": "portless myapp next dev"
  }
}
先启动一次代理(
sudo portless proxy
),然后像往常一样运行
pnpm dev
/
npm run dev

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

Bypassing portless

绕过portless

Set
PORTLESS=0
or
PORTLESS=skip
to run the command directly without the proxy:
bash
PORTLESS=0 pnpm dev   # Bypasses proxy, uses default port
设置
PORTLESS=0
PORTLESS=skip
即可直接运行命令,不经过代理:
bash
PORTLESS=0 pnpm dev   # 绕过代理,使用默认端口

How It Works

工作原理

  1. sudo portless proxy
    starts an HTTP reverse proxy on port 80 (configurable with
    --port
    )
  2. portless <name> <cmd>
    assigns a random free port (4000-4999) via the
    PORT
    env var and registers the app with the proxy
  3. The browser hits
    http://<name>.localhost
    on the proxy port; the proxy forwards to the app's assigned port
.localhost
domains resolve to
127.0.0.1
natively on macOS and Linux -- no
/etc/hosts
editing needed.
Most frameworks (Next.js, Vite, Express, etc.) respect the
PORT
env var automatically.
  1. sudo portless proxy
    会在80端口启动一个HTTP反向代理(可通过
    --port
    配置端口)
  2. portless <name> <cmd>
    会通过
    PORT
    环境变量分配一个随机空闲端口(4000-4999),并将应用注册到代理
  3. 浏览器访问代理端口上的
    http://<name>.localhost
    ,代理会将请求转发到应用分配的端口
.localhost
域名在macOS和Linux上会自动解析到
127.0.0.1
——无需修改
/etc/hosts
文件。
大多数框架(Next.js、Vite、Express等)会自动识别
PORT
环境变量。

CLI Reference

CLI 参考

CommandDescription
portless <name> <cmd> [args...]
Run app at
http://<name>.localhost
portless list
Show active routes
sudo portless proxy
Start the proxy daemon on port 80
sudo portless proxy --port <number>
Start the proxy on a custom port
sudo portless proxy stop
Stop the proxy daemon
portless --help
/
-h
Show help
portless --version
/
-v
Show version
命令描述
portless <name> <cmd> [args...]
http://<name>.localhost
运行应用
portless list
显示当前活跃的路由
sudo portless proxy
在80端口启动代理守护进程
sudo portless proxy --port <number>
在自定义端口启动代理守护进程
sudo portless proxy stop
停止代理守护进程
portless --help
/
-h
显示帮助信息
portless --version
/
-v
显示版本号

Troubleshooting

故障排查

Proxy not running

代理未运行

If
portless <name> <cmd>
reports the proxy is not running:
bash
sudo portless proxy
In 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
PORT
env var. Examples:
  • Webpack Dev Server: use
    --port $PORT
  • Custom servers: read
    process.env.PORT
    and listen on it
部分框架需要显式配置才能使用
PORT
环境变量。示例:
  • Webpack Dev Server:使用
    --port $PORT
  • 自定义服务器:读取
    process.env.PORT
    并在该端口监听

Permission errors

权限错误

The proxy requires
sudo
because port 80 is a privileged port (< 1024). Either run with
sudo
or use an unprivileged port:
bash
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
代理需要
sudo
权限,因为80端口是特权端口(<1024)。要么使用
sudo
运行,要么使用非特权端口:
bash
sudo portless proxy              # 80端口,需要sudo权限
portless proxy --port 8080       # 8080端口,无需sudo权限
sudo portless proxy stop         # 如果用sudo启动的代理,停止时也需要sudo

Requirements

系统要求

  • Node.js 20+
  • macOS or Linux
  • Node.js 20+
  • macOS 或 Linux