vercel-labs/portless
Replace port numbers with stable, named local URLs. For humans and agents.
TypeScript★ 11,880+73 that day#11 on trending
2.24%duplicated code · 323 of 14,431 lines
28clones in code
39code files of 158 scanned
7.42%duplicated over all files · 228 clones
The code number leaves out tests, fixtures, docs, examples, data files, styles, translations and vendored code.
Largest clones in the code
- 27 lines in 2 placestypescript139 tokens
335const forwardedHeaders = buildForwardedHeaders(req, reqTls); 336const proxyReqHeaders: http.OutgoingHttpHeaders = { ...req.headers }; 337for (const [key, value] of Object.entries(forwardedHeaders)) { 338 proxyReqHeaders[key] = value; 339} 340proxyReqHeaders[PORTLESS_HOPS_HEADER] = String(hops + 1); 341// Remove HTTP/2 pseudo-headers before forwarding to HTTP/1.1 backend 342for (const key of Object.keys(proxyReqHeaders)) { 343 if (key.startsWith(":")) { 344 delete proxyReqHeaders[key];First 10 of 27 lines.
- 20 lines in 2 placestypescript116 tokens
1754while (i < args.length && args[i].startsWith("-")) { 1755 if (args[i] === "--") { 1756 i++; 1757 break; 1758 } else if (args[i] === "--force") { 1759 force = true; 1760 } else if (args[i] === "--app-port") { 1761 i++; 1762 appPort = parseAppPort(args[i]); 1763 } else if (applySharingFlag(args[i])) {First 10 of 20 lines.
- 17 lines in 2 placestypescript104 tokens
174loadRoutes(persistCleanup = false): RouteMapping[] { 175 if (!fs.existsSync(this.routesPath)) { 176 return []; 177 } 178 try { 179 const raw = fs.readFileSync(this.routesPath, "utf-8"); 180 let parsed: unknown; 181 try { 182 parsed = JSON.parse(raw); 183 } catch {First 10 of 17 lines.
7 more
- 16 lines in 2 placestypescript98 tokens
- 13 lines in 2 placestypescript92 tokens
- 10 lines in 2 placestypescript87 tokens
- 12 lines in 2 placestypescript85 tokens
- 8 lines in 2 placestypescript80 tokens
- 15 lines in 2 placestypescript75 tokens
- 11 lines in 2 placesbash75 tokens
Largest clones over all files, tests and data included
- 7 lines in 6 placestypescripttests66 tokenspackages/portless/src/proxy.test.ts:1122–1128packages/portless/src/proxy.test.ts:1165–1173packages/portless/src/proxy.test.ts:1618–1626packages/portless/src/proxy.test.ts:1692–1700packages/portless/src/proxy.test.ts:1879–1887and 1 more
1122await listen(backend); 1123const backendAddr = backend.address(); 1124if (!backendAddr || typeof backendAddr === "string") throw new Error("no addr"); 1125 1126const routes: RouteInfo[] = [{ hostname: "ws.localhost", port: backendAddr.port }]; 1127const server = trackServer( 1128 createProxyServer({ getRoutes: () => routes, proxyPort: TEST_PROXY_PORT })1165await listen(backend); 1166const backendAddr = backend.address(); 1167if (!backendAddr || typeof backendAddr === "string") throw new Error("no addr"); 1168 1169const routes: RouteInfo[] = [{ hostname: "ws.localhost", port: backendAddr.port }]; 1170const server = trackServer( 1171 createProxyServer({ 1172 getRoutes: () => routes, 1173 proxyPort: TEST_PROXY_PORT, - 53 lines in 2 placestypescripttests304 tokens
12const PROXY_PORT = 19012; 13 14const isWindows = process.platform === "win32"; 15 16function killPort(port: number): void { 17 try { 18 if (isWindows) { 19 const output = execSync("netstat -ano -p tcp", { 20 encoding: "utf-8", 21 timeout: 5000,First 10 of 53 lines.
- 50 lines in 2 placestypescripttests294 tokens
22 : path.join(VENV_DIR, "bin", "python3"); 23 24/** Kill any process listening on the given TCP port (skips our own PID). */ 25function killPort(port: number): void { 26 try { 27 if (isWindows) { 28 const output = execSync("netstat -ano -p tcp", { 29 encoding: "utf-8", 30 timeout: 5000, 31 });14const isWindows = process.platform === "win32"; 15 16function killPort(port: number): void { 17 try { 18 if (isWindows) { 19 const output = execSync("netstat -ano -p tcp", { 20 encoding: "utf-8", 21 timeout: 5000, 22 }); 23 const myPid = process.pid;First 10 of 50 lines, the second copy on the right.
- 19 lines in 4 placestypescripttests98 tokens
- 10 lines in 4 placestypescripttests77 tokens
By format, code only
| Format | Files | Lines | Clones | Duplicated lines | Duplication |
|---|---|---|---|---|---|
| typescript | 23 | 13,166 | 27 | 312 | 2.37% |
| bash | 14 | 1,058 | 1 | 11 | 1.04% |
| perl | 1 | 174 | 0 | 0 | 0% |
| javascript | 1 | 33 | 0 | 0 | 0% |
By format, all files
| Format | Files | Lines | Clones | Duplicated lines | Duplication |
|---|---|---|---|---|---|
| typescript | 77 | 28,479 | 214 | 2,467 | 8.66% |
| markdown | 6 | 1,973 | 6 | 68 | 3.45% |
| tsx | 22 | 2,285 | 3 | 36 | 1.58% |
| bash | 18 | 1,240 | 1 | 11 | 0.89% |
| json | 16 | 505 | 1 | 25 | 4.95% |
| css | 2 | 347 | 1 | 7 | 2.02% |
| yaml | 4 | 278 | 1 | 14 | 5.04% |
| javascript | 8 | 135 | 1 | 6 | 4.44% |
| perl | 1 | 174 | 0 | 0 | 0% |
| text | 1 | 38 | 0 | 0 | 0% |
Trending appearances
| Day | Rank | Stars | Files | Lines | Clones | All files | Code | Health | Commit |
|---|---|---|---|---|---|---|---|---|---|
| Sep 3, 2026 | #11 | 11,880 (+73) | 158 | 35,497 | 228 | 7.42% | 2.24% | — | 1ad573b |
Want this for your own project? Install jscpd and run jscpd ., or measure it the way the baselines were measured.