{"id":28951323,"url":"https://github.com/guest271314/sockets","last_synced_at":"2026-01-20T16:54:38.503Z","repository":{"id":300602501,"uuid":"1006591715","full_name":"guest271314/sockets","owner":"guest271314","description":"TCP and UDP sockets in the browser","archived":false,"fork":false,"pushed_at":"2025-07-10T00:04:11.000Z","size":548,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-10T10:01:43.457Z","etag":null,"topics":["browser","isolated-web-apps","javascript","tcp-socket","udp-socket"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"wtfpl","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/guest271314.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}},"created_at":"2025-06-22T15:50:21.000Z","updated_at":"2025-07-03T03:17:50.000Z","dependencies_parsed_at":"2025-07-13T00:32:05.496Z","dependency_job_id":null,"html_url":"https://github.com/guest271314/sockets","commit_stats":null,"previous_names":["guest271314/sockets"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/guest271314/sockets","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guest271314%2Fsockets","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guest271314%2Fsockets/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guest271314%2Fsockets/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guest271314%2Fsockets/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/guest271314","download_url":"https://codeload.github.com/guest271314/sockets/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guest271314%2Fsockets/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268017357,"owners_count":24181669,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-31T02:00:08.723Z","response_time":66,"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":["browser","isolated-web-apps","javascript","tcp-socket","udp-socket"],"created_at":"2025-06-23T14:38:30.948Z","updated_at":"2025-07-31T09:39:02.102Z","avatar_url":"https://github.com/guest271314.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sockets\nTCP and UDP sockets in the browser using Web extension API's and Direct Sockets from an [Isolated Web App](https://github.com/WICG/isolated-web-apps/blob/main/README.md) (IWA).\n\n## Install dependencies\n\n```\nnpm install\n```\n\n```\nbun install\n```\n## Generate cryptographic keys for IWA\n\n```\ndeno -A --import-map deno.json generateWebCryptoKeys.js\n```\n\nWrite Signed Web Bundle, create Native Messaging host manifest for Node.js TCP\nand UDP local server, and writes the Native Messaging host manifest to Chromium\nconfiguration folder on Linux.\n\nUsing network imports with Deno\n\n```\ndeno -A -c deno.json index.js\n```\n\n```\nnode index.js\n```\n\nLoad the Signed Web Bundle on the command line with\n\n```\n~/chrome-linux/chrome --no-startup-window \\\n--password-store=basic \\\n--install-isolated-web-app-from-file=/home/user/sockets/signed.swbn\n```\n\nor select the `signed.swbn` file in `chrome://web-app-internals`.\n\nLoad the unpacked extension folder `sockets-web-extension` in\n`chrome://extension`, or when launching `chrome` with\n`--load-extension=/home/user/sockets/sockets-web-extension`.\n\nSet `sockets.js` to executable for launching the Node.js TCP and UDP server on\nthe local machine in a Native Messaging host.\n\nThe Web extension injects `DirectSocket` class into all `http:` and `https:` Web\npages. When constructed `DirectSocket` class starts Node.js local server, and\nopens the IWA window.\n\nCommunication between IWA window, background [MV3 `ServiceWorker`](https://developer.chrome.com/docs/extensions/develop/migrate/to-service-workers) in Web\nextension, and user determined Web page uses [`externally_connectable`](https://developer.chrome.com/docs/extensions/reference/manifest/externally-connectable); IPC that\nuses JSON-like format in Chromium browser.\n\nThe JSON from IPC is written to WHATWG Streams to implement [WICG Direct Sockets](https://wicg.github.io/direct-sockets/)\n`TCPSocket` and `UDPSocket` interfaces.\n\nNot implemented for `TCPSocketOptions`: `sendBufferSize`, `receiveBufferSize`, `dnsQueryType`.\n\n## Usage\n\nIn DevTools in an arbitrary Web page, TCP connection to remote address. Opens a\nminimal IWA window. Closing the socket closes the IWA window.\n\n```\nvar socket = new DirectSocket(\"tcp\", \"52.43.121.77\", 9001);\nvar abortable = new AbortController();\nvar decoder = new TextDecoder();\nvar {\n  readable,\n  writable,\n  remoteAddress,\n  remotePort,\n  localAddress,\n  localPort\n} = await socket.opened;\nconsole.log({\n  remoteAddress,\n  remotePort,\n  localAddress,\n  localPort\n});\nvar reader = readable.getReader();\nvar promise = reader.read().then(function read({\n  value,\n  done\n} = {\n  value: {\n    data: void 0\n  },\n  done: false\n}) {\n  if (done) return reader.closed.then(() =\u003e \"Done streaming\");\n  console.log(decoder.decode(value?.data || value));\n  return reader.read().then(read);\n}).catch((e) =\u003e e.message);\n\nawait new Response(`\n1. If a (logical or axiomatic formal) system is consistent, it cannot be complete.\n2. The consistency of axioms cannot be proved within their own system.\n\n- Kurt Gödel, Incompleteness Theorem, On Formally Undecidable Propositions \n  of Principia Mathematica and Related Systems\n`).body.pipeTo(writable, {\n  preventClose: 1\n});\npromise\n  .then((p) =\u003e {\n    console.log(p);\n  }).catch(console.warn);\n```\n\n```\nvar socket = new DirectSocket(\"tcp\", \"tcpbin.com\", 4242);\n// ...\n\nawait writer.write(new TextEncoder().encode(\"Test TCP echo server\\n\"));\nawait writer.write(new TextEncoder().encode(\"TCP echo server, again\\n\"));\nawait scheduler.postTask(() =\u003e writer.close(), {delay:300});\n\npromise\n  .then((p) =\u003e {\n    console.log(p);\n  }).catch(console.warn);\n```\n\n```\nvar socket = new DirectSocket(\"tcp\", \"guest271314.github.io\", 80);\n// ...\nawait writer.write(new TextEncoder().encode(\"GET / HTTP/1.1\\r\\n\\Host:guest271314.github.io\\r\\n\\r\\n\"));\nawait scheduler.postTask(() =\u003e writer.close(), {delay:300});\n\npromise\n  .then((p) =\u003e {\n    console.log(p);\n  }).catch(console.warn);\n```\n\nTCP connection to local machine\n\n```\nvar socket = new DirectSocket(\"tcp\", \"127.0.0.1\", 8080);\n```\n\nClose TCP connection\n\n```\nsocket.close();\n```\n\nUDP connection to remote address\n\n```\nvar socket = new DirectSocket(\"udp\", \"52.43.121.77\", 10001);\nvar abortable = new AbortController();\nvar encoder = new TextEncoder();\nvar decoder = new TextDecoder();\nvar {\n  readable,\n  writable,\n  remoteAddress,\n  remotePort,\n  localAddress,\n  localPort\n} = await socket.opened;\nconsole.log({\n  remoteAddress,\n  remotePort,\n  localAddress,\n  localPort\n});\nvar reader = readable.getReader();\nvar promise = reader.read().then(function read({\n  value,\n  done\n} = {\n  value: {\n    data: void 0\n  },\n  done: false\n}) {\n  if (done) return reader.closed.then(() =\u003e \"Done streaming\");\n  console.log(decoder.decode(value.data));\n  return reader.read().then(read);\n}).catch((e) =\u003e e.message);\n\nvar writer = writable.getWriter();\nawait writer.write({\n  data: encoder.encode(`So we need people to have weird new\nideas ... we need more ideas to break it\nand make it better ...\n\nUse it. Break it. File bugs. Request features.\n\n- Soledad Penadés, Real time front-end alchemy, or: capturing, playing,\n  altering and encoding video and audio streams, without\n  servers or plugins!`)\n});\n\npromise\n  .then((p) =\u003e {\n    console.log(p);\n  }).catch(console.warn);\n```\n\nUDP connection to local machine\n\n```\nvar socket = new DirectSocket(\"udp\", \"0.0.0.0\", 10001);\n```\n\nClose UDP connection\n\n```\nawait writer.close();\n```\n\n## License\nDo What the Fuck You Want to Public License [WTFPLv2](http://www.wtfpl.net/about/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguest271314%2Fsockets","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguest271314%2Fsockets","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguest271314%2Fsockets/lists"}