Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Server
✓ import { Server } from 'partyserver';
✗ import Server from 'partyserver';
Server is a named export, not a default export. Your Durable Object class will extend this.
routePartykitRequest
✓ import { routePartykitRequest } from 'partyserver';
✗ const { routePartykitRequest } = require('partyserver');
Used in the Worker's `fetch` handler to delegate requests to the appropriate Durable Object based on PartyKit-style routing. `partyserver` is an ESM-first library.
PartySocket
✓ import { PartySocket } from 'partysocket';
✗ import { PartySocket } from 'partyserver';
PartySocket is the recommended client library for connecting to a PartyServer instance, and is a separate package.
Demonstrates a basic PartyServer setup with a Durable Object and its lifecycle hooks, along with the necessary `wrangler.jsonc` configuration and a client-side `PartySocket` example.
import { routePartykitRequest, Server } from "partyserver";
import { PartySocket } from "partysocket";
interface Env {
MyServer: DurableObjectNamespace;
}
// Define your Server logic
export class MyServer extends Server {
onConnect(connection: WebSocket, context: any) {
console.log(`Connected ${connection.id} to server ${this.name}`);
}
onMessage(connection: WebSocket, message: string | ArrayBuffer) {
console.log(`Message from ${connection.id}:`, message);
// Broadcast the message to all other connections in the room
this.broadcast(message, [connection.id]);
}
onClose(connection: WebSocket, code: number, reason: string, wasClean: boolean) {
console.log(`Connection ${connection.id} closed. Clean: ${wasClean}`);
}
}
// Worker entry point to route requests to Durable Objects
export default {
async fetch(request: Request, env: Env): Promise<Response> {
return (
(await routePartykitRequest(request, env)) ||
new Response("Not Found", { status: 404 })
);
}
} satisfies ExportedHandler<Env>;
// === Minimal wrangler.jsonc configuration ===
/*
{
"name": "my-partyserver-app",
"main": "index.ts",
"durable_objects": {
"bindings": [
{
"name": "MyServer",
"class_name": "MyServer"
}
]
},
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["MyServer"]
}
]
}
*/
// === Client-side connection example (requires 'partysocket') ===
/*
const socket = new PartySocket({
host: "https://my-partyserver-app.threepointone.workers.dev",
party: "my-server", // 'my-server' corresponds to the kebab-cased Durable Object class name 'MyServer'
room: "my-room",
onOpen: () => console.log("Client connected!"),
onMessage: (event) => console.log("Client received message:", event.data),
onClose: () => console.log("Client disconnected"),
onError: (event) => console.error("Client error:", event)
});
// To send a message from the client
// socket.send("Hello from client!");
*/
Debug
Known issues
breakingThe method signature for `Agent#connect` in related package `partysync` (part of the broader PartyKit ecosystem) was renamed to `Agent#connectTo` to avoid collision with new TCP socket binding declarations in `@cloudflare/workers-types`.fixIf using `partysync`, update `Agent#connect(namespace, room)` calls to `Agent#connectTo(namespace, room)`.
affects: partysync@>=2.0.3
breakingPartyServer changed its internal mechanism for passing room names and properties to Durable Objects from HTTP headers to RPC. This prevents sensitive data from appearing in logs but may break compatibility with older client implementations or custom routing logic that relied on header inspection.fixEnsure both server and client libraries are up-to-date. If using `getServerByName`, it now calls `stub.setName()` via RPC, so custom stub creation might need adjustment.
affects: partyserver@>=0.4.1
gotchaUnlike PartyKit, PartyServer does not automatically infer Durable Object bindings or migrations. You must manually define `durable_objects.bindings` and `migrations` in your `wrangler.jsonc` file for each Durable Object class.fixAdd explicit `durable_objects` and `migrations` configurations to `wrangler.jsonc` as shown in the quickstart example, mapping `name` to your desired binding name and `class_name` to your exported `Server` class name.
affects: >=0.1.0
gotchaType errors can occur under newer `@cloudflare/workers-types` versions due to changes in how `fetch` and `ArrayBufferView` are handled. PartyServer aims to be compatible, but older versions might conflict.fixAlways use a compatible and recent version of `@cloudflare/workers-types` (e.g., `^4.20240729.0`) and TypeScript (`^5.0.0`) with PartyServer. Regularly update dependencies.
affects: >=0.1.0
Errors
Common errors & fixes
Error: Durable Object binding "MyServer" not found. You must configure Durable Object bindings in wrangler.toml/wrangler.jsonc.
The Durable Object binding for `MyServer` (or your equivalent class) is missing or incorrectly configured in `wrangler.jsonc`.
fixAdd or correct the `durable_objects.bindings` entry in `wrangler.jsonc`, ensuring `name` matches the `env` property used in `fetch` and `class_name` matches your exported Durable Object class name.
TypeError: 'this.broadcast is not a function' or 'this.room is undefined'
Your `Server` class likely doesn't extend `partyserver.Server`, or `this` context is lost in a callback.
fixEnsure your Durable Object class explicitly `extends Server` from `partyserver`. Verify that `this` context is preserved in methods or use arrow functions for callbacks if necessary.
Audit
Dependencies
@cloudflare/workers-typesrequiredProvides TypeScript type definitions for Cloudflare Workers API, essential for development.