TypeScript SDK
The JavaScript/TypeScript SDK is engine agnostic and can be used with any game engine or framework that supports WebSockets, such as:
- Modern web browsers (and mobile web browsers)
- Node.js
- Bun
- Electron
- React Native
- Engines/Frameworks: Phaser, PlayCanvas, React, Pixi.js, Babylon.js, THREE.js, KAPLAY, etc.
Installation
npm install --save @colyseus/sdkThe SDK includes TypeScript definitions, so you get full type support out of the box.
Initializing the SDK
import { Client } from "@colyseus/sdk";
const client = new Client("http://localhost:2567");Full Type Safety: Room State and Messages
It is recommended to provide the typeof server type as a generic to the client. This will allow the client to infer both the state type, and the message types for the room.
import { Client } from "@colyseus/sdk";
import type { server } from "../../server/src/app.config.ts";
const client = new Client<typeof server>("http://localhost:2567");import type only imports type information at compile time—no server code is included in your client bundle.
Providing Room State Types
There are two ways to get type safety for your room’s state:
Option 1: Importing the Room State Type Only
Use import type to import the state type and pass it as a generic to joinOrCreate<T>(). This gives you type inference for room.state and state callbacks.
This way, you don’t get type inference for the message name or the payload type.
import { Client } from "@colyseus/sdk";
import type { MyState } from "../server/rooms/schema/MyState";
const client = new Client("http://localhost:2567");
const room = await client.joinOrCreate<MyState>("my_room");
room.state.players // ✓ Auto-complete works
room.state.invalid // ✗ Compile error
room.onMessage("...", (client, payload) => {}); // ?? Missing type here!Option 2: Importing the Room Type Only
Use import type and pass the type as a generic to joinOrCreate<T>(). This gives you type inference for room.state and state callbacks.
import { Client } from "@colyseus/sdk";
import type { MyRoom } from "../server/rooms/MyRoom";
const client = new Client("http://localhost:2567");
const room = await client.joinOrCreate<MyRoom>("my_room");
room.state.players // ✓ Auto-complete works
room.state.invalid // ✗ Compile error
room.onMessage("...", () => {}); // ✓ Type-safeSharing Schema Classes with the Client
If you import the actual schema class (not just its type) and pass it as the third argument to joinOrCreate(), you get two benefits:
- Custom methods available — Any custom methods you’ve defined on your schema classes become accessible on the client.
- Reduced bandwidth — The server skips sending the state structure definition when the client joins, since the client already knows the schema shape.
import { Client } from "@colyseus/sdk";
import { MyState } from "../server/rooms/MyState";
const client = new Client("http://localhost:2567");
const room = await client.joinOrCreate("my_room", {}, MyState);
room.state.players // ✓ Auto-complete works
room.state.players.get("abc")?.customMethod() // ✓ Custom methods availableRoom Debug Panel
The debug panel allows you to inspect the room state and messages in real-time during development, simulate high latency conditions, connection drops, and more.
You can enable the Room Debug Panel in development mode by:
import "@colyseus/sdk/debug";
Troubleshooting: tsconfig.json Configuration
If you’re using ES2022 or ESNext and experiencing issues with state synchronization, ensure your tsconfig.json includes:
{
"compilerOptions": {
"useDefineForClassFields": false,
"experimentalDecorators": true,
"strict": true
}
}This is required for the @type() decorators to work correctly in Schema classes.
Next Steps
- Client SDK API Reference - Full API documentation for all methods, events, and room operations
- State Synchronization - Understanding Schema definitions
- State Sync Callbacks - Listen for state changes
- Phaser Tutorial - Complete game example
TypeScript
JavaScript