{"id":50940139,"url":"https://github.com/dark1zinn/libunix","last_synced_at":"2026-06-17T13:30:31.045Z","repository":{"id":362367932,"uuid":"1258509207","full_name":"dark1zinn/libunix","owner":"dark1zinn","description":"A Unix Socket handler for Javascript/TypeScript ecosystems with great DX!","archived":false,"fork":false,"pushed_at":"2026-06-03T22:48:35.000Z","size":76,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-03T23:12:52.380Z","etag":null,"topics":["bun","javascript","lib","package","socket","typescript","uds","unix","unix-sockets"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dark1zinn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-03T16:40:49.000Z","updated_at":"2026-06-03T22:48:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dark1zinn/libunix","commit_stats":null,"previous_names":["dark1zinn/libunix"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/dark1zinn/libunix","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dark1zinn%2Flibunix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dark1zinn%2Flibunix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dark1zinn%2Flibunix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dark1zinn%2Flibunix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dark1zinn","download_url":"https://codeload.github.com/dark1zinn/libunix/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dark1zinn%2Flibunix/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34451333,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-17T02:00:05.408Z","response_time":127,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bun","javascript","lib","package","socket","typescript","uds","unix","unix-sockets"],"created_at":"2026-06-17T13:30:30.432Z","updated_at":"2026-06-17T13:30:31.032Z","avatar_url":"https://github.com/dark1zinn.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# libunix\n\nUnix domain socket (UDS) IPC for [Bun](https://bun.com) and **Node.js 20+**: framed messages, `Server` / `Client`, correlation-based request/response, and lifecycle helpers. **Linux and macOS only**.\n\n## Install\n\n```bash\nbun add libunix\n# or\nnpm install libunix\n```\n\n## Usage\n\nTyped event maps mirror the integration tests: define the events your app exchanges, then wire handlers on each connected `RemotePeer`.\n\n```ts\nimport { Client, Server } from 'libunix';\n\ntype EchoEvents = {\n    echo: { msg: string };\n    [key: string]: unknown;\n};\n\nconst server = await Server.create\u003cEchoEvents\u003e({ id: 'my-app', adapter: 'bun' });\n\nconst ready = Promise.withResolvers\u003cvoid\u003e();\nserver.on('connection', (peer) =\u003e {\n    peer.onRequest('echo', (data) =\u003e ({ echo: data.msg }));\n    ready.resolve();\n});\n\nconst client = await Client.connect\u003cEchoEvents\u003e({ id: 'my-app', adapter: 'bun' });\nawait ready.promise;\n\nconst result = await client.request('echo', { msg: 'hello' });\n// { echo: 'hello' }\n\nawait client.disconnect();\nawait server.close();\n```\n\n### Socket `id`\n\n- **Logical id** (e.g. `'my-app'`): resolved to `$TMPDIR/my-app.sock` (letters, digits, `.`, `_`, `-` only).\n- **Filesystem path**: pass a path containing `/` or ending in `.sock` (e.g. `/run/myapp.sock`).\n\nOn **Bun**, omit `adapter` (defaults to `Bun.listen` / `Bun.connect`). On **Node**, omit `adapter` (auto-detects `node:net`) or pass `adapter: 'node'` explicitly.\n\n### Node.js 20+\n\nSame API; use the `node:net` transport (no extra dependencies):\n\n```ts\nimport { Client, Server } from 'libunix';\n\nconst server = await Server.create({ id: 'my-app', adapter: 'node' });\n// ... same handler wiring as above\n\nconst client = await Client.connect({ id: 'my-app', adapter: 'node' });\n```\n\nVerify on Node after build: `bun run test:node`.\n\n### One-way events (emit)\n\n```ts\ntype LoopEvents = {\n    ping: null;\n    tick: { n: number };\n    [key: string]: unknown;\n};\n\nconst server = await Server.create\u003cLoopEvents\u003e({ id: 'my-app', adapter: 'bun' });\nconst ready = Promise.withResolvers\u003cvoid\u003e();\nserver.on('connection', (peer) =\u003e {\n    peer.onRequest('ping', () =\u003e 'pong');\n    peer.on('tick', () =\u003e {});\n    ready.resolve();\n});\n\nconst client = await Client.connect\u003cLoopEvents\u003e({ id: 'my-app', adapter: 'bun' });\nawait ready.promise;\n\nawait client.emit('tick', { n: 0 });\nconst pong = await client.request('ping', null);\n\nawait client.disconnect();\nawait server.close();\n```\n\n### Errors\n\n```ts\nimport { LibunixError, isLibunixError } from 'libunix';\n\ntry {\n    await Server.create({ id: socketPath, adapter: 'bun' });\n} catch (err) {\n    if (isLibunixError(err) \u0026\u0026 err.code === 'EADDRINUSE') {\n        // socket already in use\n    }\n}\n```\n\n## Development\n\n```bash\nbun install\nbun test\nbun run build   # tsdown → dist/\n```\n\nBenchmarks (hyperfine, requires Nix dev shell): `bun run bench`. Tracked baselines live in [docs/benchmarks/](docs/benchmarks/).\n\n## Security / trust model\n\nlibunix targets **local Unix domain socket IPC** between processes on the same machine. Any process that can connect to the socket path is treated as a trusted peer (similar to any local service bound to a world-readable socket file).\n\n- Inbound envelopes always use **safe JSON parsing** (`__proto__` / `constructor` / `prototype` keys are dropped).\n- Optional **`strictEnvelope: true`** on `Server.create` / `Client.connect` rejects oversized or deeply nested JSON (`maxEnvelopeBytes`, `maxEnvelopeDepth`).\n- This is **not** authentication or encryption; do not expose UDS endpoints to untrusted networks.\n\nPublish tarball is built with [tsdown](https://tsdown.dev/guide/getting-started); `prepublishOnly` runs format check, tests, and build.\n\n## License\n\n[MIT](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdark1zinn%2Flibunix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdark1zinn%2Flibunix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdark1zinn%2Flibunix/lists"}