Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
webnet
A TypeScript monorepo for transport-based networking, anchored by a WebAssembly Tailscale SDK. It provides a layered stack of packages — from raw transport abstractions up through HTTP, WebSocket, and WebDAV — that work in browsers, Node.js, and any environment that can supply a transport.
Inspiration
This is heavily inspired by the WebVM networking stack that levrages Tailscale in the browser. Note that this doesn't lift any code from that project, only ideas.
Another inspiration is the ElysiaJS documentation that seemingly allows running a webserver from the docs directly in the browser (even if it is just a feature of the framework itself and not real networking).
How it works
Tailscale already ships a tsconnect package that compiles the IPN (in-process networking) stack to WASM via GOARCH=wasm. This repo builds on top of that with a layered set of packages:
- Patching tsconnect: the
tailscalesubmodule tracks a fork on thewebnetbranch that extends the Go-to-JS bridge (wasm_js.go) to expose lower-level networking primitives: raw TCP/UDP connections, ICMP, TLS dialing, and TCP listening. @webnet/transport: declares theRawTransport,RawListener, andRawDialerinterfaces, plus buffer utilities and transport implementations that have no external dependencies — a loopback transport and a Node.js streams adapter.@webnet/tsconnect: builds the WASM artifact, ships it alongside a Mozilla CA bundle andwasm_exec.js, and wraps the raw JS bridge in typed TypeScript classes. ItsConn,TCPListener, andIPNDialerimplement the@webnet/transportinterfaces, making it a drop-in transport source for the rest of the stack.@webnet/tsconnect-redux/@webnet/tsconnect-react: Redux Toolkit (RTK) slice and React hooks/context for IPN state management and control, extracted from the core SDK so consumers can bring their own UI framework.@webnet/http: a full HTTP/1.1 client and server over any@webnet/transportimplementation. Features include request/response streaming, chunked transfer encoding, keep-alive, a client connection pool, automatic redirect following, and a Koa-inspired middleware router.@webnet/websocket: WebSocket client and server built on@webnet/http. Handles the upgrade handshake, frame codec, masking, fragmented-message reassembly, ping/pong, and the close handshake — no external dependencies.@webnet/drive: WebDAV Level 1 (and optionally Level 2) client and server built on@webnet/http. Includes an async VFS abstraction withMemoryVFS,NodeVFS, andFsaVFS(with an OPFS factory method) implementations, acreateDAVHandler()server handler, and aDAVClientthat itself implementsAsyncVFS.
Packages
| Package | Description |
|---|---|
packages/transport |
Transport interfaces (RawTransport, RawListener, RawDialer), loopback and Node.js implementations |
packages/tsconnect |
Tailscale WASM SDK — IPN lifecycle, typed TS wrappers, transport implementation |
packages/tsconnect-redux |
RTK slice and thunks for IPN state management and control |
packages/tsconnect-react |
React hooks and context for IPN state management and control |
packages/http |
HTTP/1.1 client and server, connection pool, redirect following, Koa-inspired router |
packages/websocket |
WebSocket client and server based on @webnet/http |
packages/drive |
WebDAV (Level 1 + optional Level 2) client and server based on @webnet/http |
packages/xml |
Thin XML parse/serialize with conditional exports (native DOM / @xmldom/xmldom) |
packages/test-app |
Vite dev app for manual browser testing |
packages/example-app |
Example app demonstrating the full stack |
Submodules
The tailscale/ directory is a git submodule pointing to a fork of the Tailscale repository. The webnet branch on that fork contains the Go-side patches to tsconnect.
git submodule update --init tailscale
Development
# Build the WASM and TypeScript declarations
npm run build --workspace=packages/tsconnect
# Start the test app
npm run dev --workspace=packages/test-app
# Lint and format
npm run lint
npm run format
Commits must follow the Conventional Commits spec.
ESLint and Prettier are also required to pass.
This is enforced at commit time by husky with commitlint and lint-staged.
AI disclosure
See AI_CHANGES.md for the full log of AI-assisted and AI-authored work in this repository.