irt.io vs PartyKit
PartyKit is a framework for realtime servers. You write a server class with connection and message handlers, deploy it, and design the wire protocol yourself. irtio ships the state model instead: a typed schema, per-instance ownership, binary deltas and a tick loop.
When PartyKit is the better choice
- The realtime thing is not a game. Collaborative documents, chat, live cursors on a marketing site, presence widgets and streaming AI output are all a better fit for a general purpose realtime server than for a room with a schema and a tick rate.
- You want your own protocol. If you already have a message format, or the state is a CRDT document rather than a set of records, a state-sync system is something to work around.
- Your server has to reach other services. A PartyKit server is ordinary code, so it can call
APIs, await results and serve HTTP routes next to the socket. An irtio room handler is synchronous
and has no
fetch, which is what makes a room replayable. - You are already on that stack. Running your realtime piece in the same runtime and account as the rest of your app is worth a lot on its own.
When irt.io is the better choice
- You would otherwise write a sync engine. Deltas, join catch-up, interpolation, write batching, reconnect and correction are the parts of multiplayer that take the longest and look the most like everyone else’s. On a raw socket they are yours to build.
- Cheating matters. irtio gives every instance an owner and runs your validator on every owner write, before anyone else sees the value. Server-owned collections cannot be written by a client at all.
- The game moves continuously. A fixed-rate tick, server physics and client prediction are configuration in irtio.
- You want the game layers. Voice, simulated players, visibility filtering, saves and leaderboards are already there.
Model comparison
| PartyKit | irt.io | |
|---|---|---|
| Authority | Server, and you write what it enforces | Server, per instance, with validators |
| Who operates the server | You deploy your code to their platform | irtio |
| State model | Whatever you keep in the server object and its storage, over messages you define | Typed schema, per-instance ownership, binary deltas |
| Prediction | You write it | Built in for physics rooms, interpolation for everything else |
| Physics | Bring your own | Rapier 3D or matter.js 2D, stepped on the server |
| Voice | Not included | joinVoice(room) |
| Testing | Ordinary server tests you arrange | In-process rooms on a fake clock, plus simulated players over real sockets |
| Hibernation and idle cost | Servers sleep when idle and wake on the next connection | Rooms sleep after idleMs and wake with state intact |
| Language | TypeScript or JavaScript, browser clients | TypeScript, browser clients |
What porting looks like
Both sides are already room-shaped, so the port is mostly about deleting your protocol.
List the message types your server handles. Each one becomes one of two things. A message that
reports what a player did to something they control becomes an owned write: put the record in the schema, add it in onJoin with { owner: ctx.clientId }, and the client
assigns to it. The message type, its encoder, its decoder and its handler all go away. A message
that asks the server to decide something becomes an RPC against a
server-owned collection, which keeps its handler almost unchanged.
Then delete the broadcast half. Anything that serializes state and pushes it to connections is
replaced by the room’s own delta flush, and anything on the client that applies those updates is
replaced by reading room.state and drawing room.render.
Two pieces need a new home. Storage on the server object maps onto room state plus saves and player storage, and a scheduled wake-up maps onto alarms. Anything that awaited an external service has to move out of the room, because handlers are synchronous.
On the client, your socket becomes joinRoom(schema). The reconnect and backoff code you wrote
around it is not needed.
Next steps
- The mental model for ownership and the ladder.
- State and schema for the field types and collections.
- Retrofitting an existing game for adding irtio to code that already runs.
- Deploying a room for what replaces your deployment.
This page describes each product’s model as it stood at the page’s last review. Send corrections to hello@irt.io.