Client SDK
The Client SDK provides everything you need to connect to a Colyseus server from your game or application.
Client Setup
The Client instance is your entry point to connect to the server.
import { Client } from "@colyseus/sdk";
const client = new Client("http://localhost:2567");
// ... with full-stack type safety (optional)
import type { server } from "../../server/src/app.config.ts";
const client = new Client<typeof server>("http://localhost:2567");Joining Rooms
Once you have a client, you can join rooms. Choose the method that best fits your matchmaking needs.
Join or Create (Recommended)
The most common way to connect. Joins an existing room if available, or creates a new one.
try {
const room = await client.joinOrCreate("battle", {/* options */});
console.log("joined successfully", room);
} catch (e) {
console.error("join error", e);
}Locked or private rooms are ignored by this method.
Other Join Methods
These methods use the same pattern as joinOrCreate. Replace the method name accordingly.
| Method | Signature | Description |
|---|---|---|
create | client.create(roomName, options) | Always creates a new room, even if others exist. |
join | client.join(roomName, options) | Joins an existing room. Fails if none available. Locked/private rooms are ignored. |
joinById | client.joinById(roomId, options) | Joins a specific room by its unique ID. Private rooms can be joined by ID. Useful for invite links. |
consumeSeatReservation | client.consumeSeatReservation(reservation) | Joins using a pre-reserved seat from the server. See Matchmaker → Reserve Seat For. |
You may disallow the client from creating rooms. See Matchmaker → Restricting the frontend from creating rooms
Example: Creating an invite link with joinById
// Share the room ID with other players
const inviteLink = `https://mygame.com/join?roomId=${room.roomId}`;
// On the receiving end, parse the room ID and join
const params = new URLSearchParams(window.location.search);
const room = await client.joinById(params.get("roomId"));Send and Receive Messages
Once connected to a room, you can send and receive messages in real-time, including raw byte payloads and request/response. See Sending & Receiving Messages for the full reference.
Sending Input (Netcode)
For prediction-ready rooms (rooms that call defineInput() on the server), room.input() returns a typed input channel: stage fields on input.data, then input.send() once per fixed step.
const input = room.input(); // input schema arrives from the server's defineInput()
input.data.moveX = 1;
input.data.jump = true;
input.send();Inputs are buffered and acknowledged, and power client-side prediction and lag compensation. See room.input(options) for the full reference: reliability modes, redundancy, and the InputHandle surface.
The netcode APIs (room.input(), room.clock, Predict) are available in Colyseus 0.18+ across the official SDKs. See Client Prediction.
State Synchronization
The room state is automatically synchronized from the server to all connected clients. The room.state property always contains the latest state.
State Sync Callbacks (Recommended)
Use Callbacks to listen for specific property changes with fine-grained control.
import { Callbacks } from "@colyseus/sdk";
const callbacks = Callbacks.get(room);
callbacks.listen("currentTurn", (currentValue, previousValue) => {
console.log("Turn changed:", previousValue, "->", currentValue);
});
callbacks.onAdd("players", (player, sessionId) => {
console.log("Player joined:", sessionId);
callbacks.listen(player, "hp", (currentHp, previousHp) => {
console.log("Player", sessionId, "hp:", currentHp);
});
});
callbacks.onRemove("players", (player, sessionId) => {
console.log("Player left:", sessionId);
});See the full State Sync Callbacks documentation for all available methods including listen, onAdd, onRemove, and more.
On State Change
The onStateChange event fires whenever the server synchronizes state updates. Use this when you need to know something changed, without tracking individual properties.
room.onStateChange((state) => {
console.log("the room state has been updated:", state);
});Read more about State Synchronization
Connection Lifecycle
Leaving a room, automatic and manual reconnection, error handling, and removing listeners. See Connection Lifecycle & Reconnection for the full reference.
Latency & Server Selection
Measure network latency and choose optimal servers for your players.
Measuring Latency
Before Joining
Create a temporary connection to measure latency before joining a room.
Parameters
options.pingCount: Number of pings to send (default:1). Returns the average latency when greater than 1.
const latency = await client.getLatency();
console.log("Latency:", latency, "ms");
// With multiple pings for a more accurate average
const avgLatency = await client.getLatency({ pingCount: 5 });
console.log("Average Latency:", avgLatency, "ms");During a Room Connection
Measure round-trip time on an existing connection.
room.ping((latency) => {
console.log("Latency:", latency, "ms");
});If the connection is not open, calling ping() has no effect.
Multi-Region Server Selection
Automatically connect to the server with the lowest latency from a list of endpoints.
Parameters
endpoints: Array of server endpoints (URLs or endpoint settings objects).options: Optional client options to pass to each client instance.latencyOptions.pingCount: Number of pings to send per endpoint (default:1).
import { Client } from "@colyseus/sdk";
// Select the best server from multiple regions
const client = await Client.selectByLatency([
"https://us-east.gameserver.com",
"https://eu-west.gameserver.com",
"https://asia.gameserver.com",
]);
// Now use the client with the lowest latency
const room = await client.joinOrCreate("game");The method logs the latency for each endpoint to the console for debugging purposes. If all endpoints fail to respond, an error is thrown.
HTTP Requests
The client.http utility performs HTTP requests to your server endpoint. The client.auth.token is sent automatically as an Authorization header.
// GET
const response = await client.http.get("/profile");
// POST
const response = await client.http.post("/profile", { body: { name: "Jake" } });
// PUT
const response = await client.http.put("/profile", { body: { name: "Jake" } });
// DELETE
const response = await client.http.delete("/profile");See Server → HTTP Routes for setting up HTTP endpoints on your server, and Authentication → HTTP Middleware for securing them.
Room Reference
Quick reference for room properties.
| Property | Type | Description |
|---|---|---|
state | any | The synchronized room state from the server |
sessionId | string | Unique identifier for the current client connection |
roomId | string | Unique room ID (shareable for direct joins) |
name | string | Name of the room type (e.g., "battle") |
reconnectionToken | string | Token for manual reconnection |
reconnection | ReconnectionOptions | Automatic reconnection configuration |
clock | RoomClock | Server time & latency estimates (serverNow(), rtt()). See room.clock |
Next Steps
- State Sync Callbacks - Listen for state changes on the client
- Netcode - Predict local input and reconcile to server state
- Room API - Server-side room implementation
- Authentication - Secure your room connections
- Tutorials - Step-by-step game implementations