codingetandClaude 1689c2eacc feat(transport): add explicit TLS upgrade (STARTTLS / AUTH TLS) to RawTransport
Adds an optional in-place upgradeTls(options) method and an isTls
getter to RawTransport, implemented on the node and tsconnect
transports. Client mode takes serverName/insecureSkipVerify/caCerts
(serverName required unless skipping verification); server mode takes
isServer with a PEM cert/key pair. Upgrading requires a quiescent
transport and closes the connection on handshake failure.

NodeTransport wraps its existing socket with node:tls; tsconnect's
Conn swaps its raw handle via the new upgradeTLS wasm bridge method
(tailscale submodule bump); tsconnect-worker forwards the upgrade over
new per-conn protocol messages and carries isTls on conn/accepted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XfRgMke8p7QDxD5QM5thxH
2026-07-12 14:08:40 +00:00
2026-06-23 22:13:38 +00:00
2026-07-12 01:52:36 +00:00
2026-06-23 22:13:38 +00:00

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:

  1. Patching tsconnect: the tailscale submodule tracks a fork on the webnet branch 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.
  2. @webnet/transport: declares the RawTransport, RawListener, and RawDialer interfaces, plus buffer utilities and transport implementations that have no external dependencies — a loopback transport and a Node.js streams adapter.
  3. @webnet/tsconnect: builds the WASM artifact, ships it alongside a Mozilla CA bundle and wasm_exec.js, and wraps the raw JS bridge in typed TypeScript classes. Its Conn, TCPListener, and IPNDialer implement the @webnet/transport interfaces, making it a drop-in transport source for the rest of the stack.
  4. @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.
  5. @webnet/http: a full HTTP/1.1 client and server over any @webnet/transport implementation. Features include request/response streaming, chunked transfer encoding, keep-alive, a client connection pool, automatic redirect following, and a Koa-inspired middleware router.
  6. @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.
  7. @webnet/drive: WebDAV Level 1 (and optionally Level 2) client and server built on @webnet/http. Includes an async VFS abstraction with MemoryVFS, NodeVFS, and FsaVFS (with an OPFS factory method) implementations, a createDAVHandler() server handler, and a DAVClient that itself implements AsyncVFS.

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

# Expose a development app to a trusted remote host or reverse proxy
npm run dev:host --workspace=packages/test-app

# Lint and format
npm run lint
npm run format

Remote-host development

Development apps provide two deliberate modes:

  • npm run dev --workspace=packages/<app> is local-only and retains the dev server's host-header protections.
  • npm run dev:host --workspace=packages/<app> binds to all network interfaces and accepts forwarded hostnames. Use it only on a trusted network, such as a Tailnet or an authenticated code-server proxy: a dev server can expose source maps, development endpoints, and application credentials or state.

The hosted mode leaves the HMR websocket URL relative to the page URL, so it works through a reverse proxy without baking a container or localhost address into the app. Configure that proxy to forward WebSocket upgrade requests (Upgrade and Connection headers) to the dev server, including the Vite HMR endpoint or webpack-dev-server's /ws endpoint.

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.

S
Description
No description provided
Readme
3.3 MiB
Languages
TypeScript 98.8%
JavaScript 0.6%
Shell 0.2%
SCSS 0.2%
HTML 0.1%