Skip to content

One session.
Two delivery modes.

Multiplayer networking for browser games. Reliable, ordered events for actions that must arrive. Fresh, replaceable state for movement and snapshots. One player session survives dropped connections, app switches and Wi-Fi hand-offs. Your server owns the game; Twinwire keeps the session.

WebSocket carries the session and reliable events. State can use WebRTC or optional WebTransport over HTTP/3, with WebSocket fallback. WebTransport requires a configured HTTP/3 host and browser support; every datagram path must prove itself.

MIT licensed · Node 22+ · Chromium, Firefox & WebKit tested

States ride the WebSocket until the datagram path proves itself both ways.

Interactive simulation. Two Twinwire endpoints run locally in this page, exchanging real frames over a simulated network, slowed down so you can watch. Block UDP, and within 1.5 seconds of game time everything is on the WebSocket, without the session noticing.

Try a reconnect ​

The same player can outlive a socket. Click Drop the connection and watch it resume automatically. The session ID and lobby seat stay the same within the grace period; unacknowledged events replay once. This runs Twinwire's session code in a local simulation. What the demo does · All seven interactive lessons

OnlineConnection attemptAttempt failedSeat in useSeat held for the player
Client idleSession noneConnection epoch 0Resumed 0 timesEvents waiting to be acknowledged 0

What it does ​

Your game keeps its rules, physics and rendering. Twinwire carries the bytes and the session; your server decides what is true.

Two wires, one session

State rides WebRTC datagrams while probes prove the path works both ways, and moves to the WebSocket within about 1.5 s when it stops. One UDP port on the server for every player.

Sessions that survive

A dropped connection resumes the same session: same identity, same lobby seat, unacknowledged events replayed both ways. A reload with a checkpoint keeps the seat too.

Events at UDP speed

Ordered, acknowledged JSON events go on the WebSocket and race a copy on the datagrams. Whichever lands first is delivered, once, in order.

State, latest wins

Binary streams that coalesce and expire instead of queueing, up to 64 KiB, with acknowledgements so you can send deltas against what each player has.

A lobby

Private rooms with codes, quick play matched by mode and build, stable seats, host hand-off, ready-up with a countdown, kick, rate limits.

Netcode helpers

Clock sync, snapshot interpolation with adaptive delay, prediction and reconciliation, input redundancy, fixed steps, interest queries, binary codecs.

STUN and TURN

ICE servers handed to each client by your server, so you can rotate them without a new build: coturn credentials or Cloudflare’s managed relay.

An optional QUIC path

Add WebTransport beside WebRTC. Each path has its own proof, payload limit and RTT; path changes keep the same logical player.

See where time goes

Bounded metadata separates send queues, receipt, world application, playback and render submission. Fetch large resources independently of ordered gameplay actions.

Browser first

Tested in Chromium, Firefox and WebKit against the real server, on a bad network and with UDP blocked. See the measured support and release checks.

Two delivery modes, three transport options ​

The modes describe how messages behave. The transport is the path carrying them.

Delivery modeWhat it doesWhere it travels
Reliable eventsDelivers actions in order, acknowledges them and replays unacknowledged events after reconnectingWebSocket, with copies racing on the selected proven datagram path
Replaceable stateSends the latest movement or world snapshot, coalescing and expiring older updatesProven WebRTC or WebTransport datagrams, with WebSocket fallback

WebTransport support is optional and available in 3.0. It adds an HTTP/3 QUIC datagram path alongside WebRTC. Configure a compatible Node host with a trusted TLS certificate and UDP routing. Each connection needs browser support and two-way probe replies before Twinwire selects that path. Browsers without it continue with WebRTC or WebSocket; the Worker host and live starter use WebSocket.

The client still establishes its session over WebSocket. A transport change keeps the same logical player. Path selection uses measured probe RTT, payload limits and a hold time; performance depends on the workload and network. Set up WebTransport · Understand path selection

Start with a running game ​

Play the live arena in two tabs using the same invite URL. Move, send a reliable ping, and disconnect for two seconds. This is a real hosted WebSocket game, with a separate private arena per invite. The downloadable Node version also supports native WebRTC.

Download the standalone starter, extract it, then run:

sh
npm install
npm start

Open http://127.0.0.1:8787 in two tabs. Move your player, send a reliable ping, disconnect for two seconds, and reload the page. Your ID and score survive the interruption. The starter uses the published package and serves its own browser module; no bundler or account is needed.

Read the complete walkthrough · Browse the starter source

Already have a game? Port an existing transport, keep your current simulation, and deploy the client and server together. For rooms, ready-up, prediction and chat, start from the party example.

Used in real games ​

  • Nocturne Keep: a pixel-art co-op platformer. Persistent worlds and combat remain game-owned.
  • kimu.nyc: a shared city, with interest groups and adaptive playback for nearby players.
  • CS2 browser prototype: authoritative shooter movement, fire events and paired client/server releases.

Twinwire 3.0 also runs in eight more games, including Oak0, a turn-based Worker game and several arena games. Explore all eleven live integrations. Read the release evidence and its limits.

What you bring ​

Twinwire is a library, under the MIT license. You host a Node server or a compatible Worker, plus your client, choose your physics and serialization, and validate player actions. It does not supply a database, an account system, or a global room allocator. A WebSocket is enough to start; native WebRTC is optional.

Deployment and TURN · API reference · Report a reproducible issue

MIT licensed. Source on GitHub, package on npm.