a13n
Build AI agents and run them on cloud.
One session, two wires: WebSocket for what must arrive, WebRTC datagrams for what must arrive fast. With a lobby, automatic reconnects and snapshot recovery.
Developer toolsJavaScript · TypeScriptGitHub @studiokimeigaOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Multiplayer networking for browser games: one resumable session on two wires (WebSocket + WebRTC datagrams), a lobby, and netcode helpers. Works in every browser, iPhone Safari included.
Taken from the repository README
Loading the full README.
Read the full README ↗Multiplayer networking for browser games. One player session: WebSocket for what must arrive, WebRTC datagrams for replaceable realtime state, and an optional WebTransport fast path. Twinwire picks a proven path when the network allows it, falls back to the WebSocket the moment it doesn't, and keeps the player's session (and seat) through dropped connections, app switches and Wi-Fi-to-cellular hand-offs. It comes with a lobby (room codes, quick play, ready-up) and the netcode helpers an authoritative-server game needs.
npm install twinwire
npm install node-datachannel # on the server, for WebRTC (optional: without it, WebSocket only)
Browser games that want to feel good online hit the same wall: WebSocket is TCP, so one lost packet holds up every packet behind it, and on a phone that's a stutter. WebRTC data channels can be unreliable and unordered like UDP, but they're fiddly to set up, they fail on some networks, and a channel that says "open" isn't proof that packets get through. Then there's everything around it: reconnecting without losing your place, rooms and invite codes, interpolating other players, predicting your own.
Twinwire does that part, so the game can be the game:
SnapshotHistory, diffEntities).receiveState resets or retains a stream's history according to policy and holds playback
until usable fresh data arrives after reconnecting. A connected socket or retained clock cannot release it alone.Your game keeps its rules, physics and rendering. Twinwire carries the bytes and the session; your server decides what is true.
3.0 uses wire generation 5: upgrade clients and servers together. See transport, tracing and resource controls for migration, optional HTTP/3 hosting and measured limits.
Start with the complete standalone arena: install its locked dependencies, run
npm start, and open http://localhost:8787 in two tabs. Move with WASD/arrows or drag on touch screens, send a
reliable ping, then disconnect for two seconds and check that the player identity, position and score survive.
The client and server code is included; no undefined game-engine helpers or bundler are needed.
The getting started guide includes a downloadable project and deployment instructions. The party example adds room codes, matchmaking, prediction and interpolation. For an existing game, named channels preserve familiar message names and room membership while making pause, fresh-state recovery and terminal expiry explicit. For Durable Objects or another standard-WebSocket host, see the Worker adapter.
Your game still validates commands, owns physics and persistence, and decides when a complete snapshot or durable board is usable. See snapshot recovery before attaching a renderer to raw callbacks.
Play the hosted starter: a real private-invite arena, authoritative movement, ordered ping score and same-ID recovery over WebSocket. Worker source; no claim of durable transport storage.
examples/party: a complete little game. Quick play or a room by code, ready-up, then move
around a shared arena and chat. Server-authoritative movement with client-side prediction and reconciliation, other
players interpolated, inputs sent redundantly. About 300 lines. npm run build && npm run example, then open
http://127.0.0.1:8790 in two tabs (RTC=1 for WebRTC).
examples/arena: the transport on its own, with live numbers (path, RTT, bytes).
npm run demo.
The 2.1 release is used in CS2, kimu.nyc and Nocturne Keep: co-op story, maker rooms and a roguelike played together, with the game's own code running each room's world on a $5 server.
studiokimeiga.github.io/twinwire: the guide, how each piece works (with live demos that run the library in your browser), and the reference.
npm install
npm run check # build + unit and localhost integration tests
npm run test:native # Node WebRTC client <-> native server: datagrams, fallback, recovery
npx playwright install chromium firefox webkit
npm run test:browser # real browsers <-> native server (also IMPAIR=1, RTC=0)
npm run test:example # the party example, played in three browsers
Twinwire was created by Hakan Alpay and is maintained under Studio Kimeiga.
For research, technical writing, or presentations that reference Twinwire, use GitHub's Cite this repository menu or the machine-readable CITATION.cff. For games or tools that use Twinwire, a link to the project is appreciated, though it is not a condition of the MIT license. Copies or substantial portions of Twinwire must retain the applicable copyright and license notice.
Contributions are welcome: see CONTRIBUTING.md. Community support is provided on a best-effort basis; see SUPPORT.md. Report vulnerabilities privately as described in SECURITY.md.
MIT licensed; see LICENSE.