Skip to content

feat: add unix option for listening on a unix socket - #327

Open
pi0x wants to merge 4 commits into
mainfrom
feat/unix-socket
Open

pi0x wants to merge 4 commits into
mainfrom
feat/unix-socket

Conversation

@pi0x

@pi0x pi0x commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Adds a generic unix server option (next to port / hostname) that maps to each runtime's native unix socket listener:

Runtime Native mapping
Node.js server.listen({ path }) (also accepts Windows named pipes)
Bun Bun.serve({ unix })
Deno Deno.serve({ transport: "unix", path })
serve({ unix: "/tmp/app.sock", fetch: () => new Response("ok") });
serve({ unix: true, fetch }); // random socket, like `port: 0`

Behavior

  • Precedence: when unix is set, port / hostname and PORT / HOST are not resolved. Runtime-specific listen options (node.path, bun.unix, deno.path, …) still take precedence.
  • server.url: the socket path on all three runtimes. Node already did this; Bun and Deno now match. Linux abstract sockets (\0name) work on all three and print as @name.
  • unix: true: picks a random socket (inspired by get-port-please):
    • a named pipe on Windows;
    • an abstract socket on Linux (no file, so it can never go stale);
    • a file in the temp dir elsewhere.
  • Stale socket cleanup: a socket file left behind by a crashed process (SIGKILL, OOM, no graceful shutdown) used to make the next listen fail with EADDRINUSE.
    • When: cleanup runs only after a listen fails with EADDRINUSE, so successful listens are unaffected.
    • Removed: only a path that is a socket file and refuses connections. It is unlinked after re-checking its inode, then the listen is retried once.
    • Never touched: live sockets, regular files, directories, abstract sockets and named pipes. This is unlike get-port-please's cleanSocket(), which runs rm -rf on the path.
  • Request URLs without a Host header on a unix socket now become http://localhost/...:
    • Node previously built http://undefined:80/....
    • Deno's native URL is http+unix:// (a non-special scheme, so origin is "null"). The adapter now rewrites it to http://<host> by overriding url in place, with no request rebuild and no request.signal legacy warning.
  • Deno + TLS: Deno silently ignores cert / key on a unix socket and serves plaintext, so unix combined with tls now throws instead of downgrading.
  • CLI: a unix exported by the entry yields to explicit --port / --host flags. Dev-mode --watch restarts work thanks to the stale cleanup.

Tests

test/_unix-socket.ts is a shared suite run under Node, Bun and Deno (test/{node,bun,deno}-unix-socket.test.ts) through fixtures/unix-socket-server.ts. It checks:

  • the request body and url / origin;
  • Host-less requests (Node and Deno);
  • the socket file is removed on close;
  • no stderr warnings;
  • a stale socket is removed, while a live socket and a regular file are left alone;
  • unix: true;
  • TLS over the socket (Node and Bun) and the TLS refusal (Deno).

The Bun and Deno test files are added to their CI jobs. Verified locally on Node 24, Bun 1.4.2, and Deno 2.9.6 plus the CI-pinned 2.7.12. Deno before 2.9 reports path: null for abstract sockets, which is handled.

Known limitations / follow-ups

  • A live server whose accept backlog is full also refuses connections on Bun and macOS, so the stale check could take over its path. This needs a stalled, overloaded server and is noted in the code.
  • unix: true on Windows with Bun or Deno is untested; named-pipe support in their unix transports is unknown.
  • Bun returns a relative request.url (e.g. /bar) for Host-less requests on TCP as well. This is an existing issue, not specific to unix sockets.
  • A unix socket peer has no IP, so trustProxy: "loopback" never matches. This is documented (use trustProxy: true).
  • A --unix CLI flag.

🤖 Generated with AI assistant

Summary by CodeRabbit

  • New Features

    • Added support for serving applications over Unix domain sockets across Node.js, Bun, and Deno.
    • Supports explicit or automatically generated socket paths, including platform-specific socket formats.
    • Server URLs now expose Unix socket addresses.
  • Bug Fixes

    • Automatically replaces stale socket files while preserving active sockets and regular files.
    • Clarified command-line precedence when host or port options are provided.
  • Documentation

    • Added configuration, runtime behavior, limitations, and CLI guidance for Unix sockets.
  • Tests

    • Added cross-runtime coverage for requests, cleanup, stale sockets, random paths, and TLS behavior.

@pi0x
pi0x requested a review from pi0 as a code owner October 20, 2026 01:39
@vercel

vercel Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
srvx Ready Ready Preview Oct 20, 2026 1:54am UTC

Request Review

@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 830a1da6-00a7-48f0-96f8-9bd4969f9fd2
📥 Commits

Reviewing files that changed from the base of the PR and between 7bcdbaf and 0e9af6e.

📒 Files selected for processing: 11
  • docs/1.guide/05.options.md
  • src/_utils.ts
  • src/adapters/_node/url.ts
  • src/adapters/bun.ts
  • src/adapters/deno.ts
  • src/adapters/node.ts
  • src/cli/serve.ts
  • src/types.ts
  • test/_unix-socket.ts
  • test/fixtures/unix-socket-server.ts
  • test/node-unix-socket.test.ts
💤 Files with no reviewable changes: 1
  • src/cli/serve.ts

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.

📝 Walkthrough

The server options and Node.js, Bun, and Deno adapters now support Unix sockets. The change adds platform-specific socket resolution, stale-socket handling, CLI precedence, documentation, and cross-runtime tests.

Changes: Unix Domain Socket Support

Layer / File(s) Summary
Define and resolve Unix socket options
src/types.ts, src/types/deno.ts, src/_utils.ts
ServerOptions accepts a socket path or true for a random socket. Utilities resolve platform-specific addresses, safely remove stale filesystem sockets, and format Linux abstract socket addresses.
Listen on Unix sockets in runtime adapters
src/adapters/node.ts, src/adapters/bun.ts, src/adapters/deno.ts, src/adapters/_node/url.ts
The adapters listen on resolved socket addresses, handle stale-socket startup errors, and report socket URLs. Deno normalizes Unix-socket request URLs and rejects TLS with Unix sockets.
Apply CLI precedence and document socket options
src/cli/serve.ts, docs/1.guide/05.options.md, docs/1.guide/10.cli.md
An exported Unix socket is used unless explicit CLI port or host flags are set. The guides describe the option, runtime mappings, and CLI precedence.
Test Unix sockets across runtimes
test/_unix-socket.ts, test/fixtures/unix-socket-server.ts, test/*-unix-socket.test.ts, .github/workflows/ci.yml
Shared integration tests cover requests, cleanup, stale and active sockets, random sockets, and TLS behavior. Node.js, Bun, and Deno suites use the shared fixture; CI runs the Bun and Deno suites.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Merge Risk: ⚪ Minimal · up to 0e9af

This change adds a Unix socket option for Node, Bun, and Deno, along with CLI precedence rules and tests. No actionable merge-blocking risk was identified in the reviewed changes.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 14 files. (1 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: adding the unix server option for Unix socket listening.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 14 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit taps the socket door,
Then hops through paths from shore to shore.
Stale files vanish when safe to do,
Three runtimes answer, quick and true.
The moonlit burrow hums with cheer.

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 39.70588% with 41 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/_utils.ts 19.51% 27 Missing and 6 partials ⚠️
src/adapters/node.ts 78.26% 5 Missing ⚠️
src/cli/serve.ts 0.00% 1 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

@pkg-pr-new

pkg-pr-new Bot commented Oct 20, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/srvx@327

commit: 0e9af6e

This branch was successfully deployed

1 active deployment
Preview — 0e9af6e7 Deployed Oct 20, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants