You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
Codinget 46bb960198 fix(tsconnect): bump tailscale submodule and expose done on incoming files 21 hours ago
.husky chore: add prettier, eslint, dpdm, lint-staged, commitlint; bump TS to 6 6 days ago
packages fix(tsconnect): bump tailscale submodule and expose done on incoming files 21 hours ago
tailscale@e32520659d fix(tsconnect): bump tailscale submodule and expose done on incoming files 21 hours ago
.gitignore feat: initialize npm monorepo with tsconnect wasm package 1 week ago
.gitmodules chore: point tailscale submodule to gitea mirror 1 week ago
.prettierignore chore: add prettier, eslint, dpdm, lint-staged, commitlint; bump TS to 6 6 days ago
.prettierrc.json chore: add prettier, eslint, dpdm, lint-staged, commitlint; bump TS to 6 6 days ago
README.md docs: document @webnet/http package in README 5 days ago
commitlint.config.js chore: add prettier, eslint, dpdm, lint-staged, commitlint; bump TS to 6 6 days ago
eslint.config.js chore: add prettier, eslint, dpdm, lint-staged, commitlint; bump TS to 6 6 days ago
package-lock.json feat(http): implement http server library inspired by koa 5 days ago
package.json chore: add prettier, eslint, dpdm, lint-staged, commitlint; bump TS to 6 6 days ago

README.md

webnet

A TypeScript/WebAssembly SDK for running Tailscale inside a browser. It wraps the existing tsconnect Go package from the Tailscale repository, compiles it to WASM, and exposes a typed JavaScript API for joining a tailnet, opening TCP connections, dialing TLS, and listening, all from within a web page.

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 by:

  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/tsconnect: an npm package (packages/tsconnect) that 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 with argument validation to avoid a Go panic that kills the WASM instance.
  3. @webnet/test-app: a Vite dev app (packages/test-app) for manual browser testing. It exposes initIPN, wasmURL, cacertURL, and loadCACerts on window so the full stack can be exercised from the browser console without writing any test code.
  4. @webnet/http: an HTTP/1.1 server library (packages/http) built on top of the RawTransport/RawListener primitives exposed by @webnet/tsconnect. Implements request parsing, chunked transfer encoding, keep-alive, a middleware/router system, and response serialisation. Supports any stream transport that can implement these interfaces.

Packages

Package Description
packages/tsconnect The SDK: builds the WASM, exports typed TS wrappers
packages/http HTTP/1.1 server library over any stream transport
packages/test-app Vite dev app for manual browser testing

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

This project was set up with the assistance of Claude Code (Anthropic). The following were written by Claude Code:

  • The tailscale submodule fork and its Go-side tsconnect patches (the webnet branch)
  • The packages/tsconnect TypeScript SDK
  • The packages/test-app Vite test application
  • The repo tooling setup (ESLint, Prettier, lint-staged, commitlint, dpdm, TypeScript 6)

The following were hand written, but with support from Claude Code for spec guidance, sanity checking and bug spotting:

  • The packages/http HTTP/1.1 server library