Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/cloudflare/partykit/llms.txt

Use this file to discover all available pages before exploring further.

The Server class is the core building block of PartyServer. Extend it to create a Durable Object that manages WebSocket connections with structured lifecycle hooks, built-in broadcasting, and an optional hibernation mode. Every server instance is addressed by name, making it straightforward to associate a server with a room ID, session, or any other application-level identifier.

Class definition

class Server<
  Env extends Cloudflare.Env = Cloudflare.Env,
  Props extends Record<string, unknown> = Record<string, unknown>
> extends DurableObject<Env>
Server extends the Cloudflare DurableObject base class. The generic parameter Env is inferred from your Worker’s environment bindings as declared in wrangler.jsonc. The optional Props generic allows typed initial properties delivered by routePartykitRequest or getServerByName.

Static options

static options: { hibernate?: boolean } = { hibernate: false };
Set options.hibernate = true to enable WebSocket Hibernation. When hibernation is enabled the Durable Object is evicted from memory between messages, dramatically reducing CPU costs for low-traffic servers. All lifecycle hooks are called exactly as they would be in non-hibernating mode. Subclasses inherit the nearest explicitly declared hibernate value — declaring partial options on a child class does not disable hibernation configured on a parent.
export class MyServer extends Server {
  static options = { hibernate: true };
}

Lifecycle hooks

All lifecycle hooks are optional. Override only the ones your application needs. Every hook can be synchronous or async.

onStart

onStart(props?: Props): void | Promise<void>
Called once when the server starts for the first time and again each time it wakes from hibernation. Use this hook to load data from Durable Object storage, fetch remote configuration, or perform any other one-time setup. this.name is available when onStart runs.
props
Props
Optional initial properties delivered via routePartykitRequest or getServerByName. Typed by the Props generic parameter of the class.

onConnect

onConnect(connection: Connection, ctx: ConnectionContext): void | Promise<void>
Called when a new WebSocket connection is accepted. Use this hook to store per-connection state, send a welcome message, or perform authentication follow-up.
connection
Connection
The newly established connection. See Connection for the full interface.
ctx
ConnectionContext
Contains the original HTTP upgrade Request. See ConnectionContext.

onMessage

onMessage(connection: Connection, message: WSMessage): void | Promise<void>
Called each time a message arrives from a connected client.
connection
Connection
The connection that sent the message.
message
WSMessage
The received message. WSMessage is string | ArrayBuffer | ArrayBufferView.

onClose

onClose(
  connection: Connection,
  code: number,
  reason: string,
  wasClean: boolean
): void | Promise<void>
Called when a client closes its connection. By the time this hook fires the WebSocket is already closed and can no longer send or receive messages.
connection
Connection
The connection that was closed.
code
number
The WebSocket close code sent by the peer (e.g. 1000 for a normal closure).
reason
string
Human-readable reason string accompanying the close code.
wasClean
boolean
true if the connection was closed via the proper WebSocket closing handshake.

onError

onError(connection: Connection, error: unknown): void | Promise<void>
Called when a WebSocket error occurs on a connection. PartyServer suppresses benign transport-teardown errors that occur during or after the close handshake; only genuine mid-connection errors reach this hook.
connection
Connection
The connection on which the error occurred.
error
unknown
The error value. May be an Error instance or a raw value depending on the runtime.

onRequest

onRequest(request: Request): Response | Promise<Response>
Called for every plain HTTP request routed to this server (i.e. requests that are not WebSocket upgrade requests). Returns a Response. The default implementation returns 404 Not implemented.
request
Request
The incoming HTTP request.
return
Response | Promise<Response>
The HTTP response to send to the client.

onAlarm

onAlarm(): void | Promise<void>
Called when a Durable Object alarm fires. Schedule alarms via this.ctx.storage.setAlarm(date). Read more about Durable Object alarms.
Do not override the alarm() method directly — override onAlarm() instead. PartyServer’s alarm() implementation calls onAlarm() after ensuring the server is fully initialized.

getConnectionTags

getConnectionTags(
  connection: Connection,
  context: ConnectionContext
): string[] | Promise<string[]>
Return an array of string tags to attach to a connection at accept time. Tags are used to filter the results of getConnections(). Each connection supports up to 9 tags and each tag may be at most 256 characters long. The default implementation returns an empty array.
connection
Connection
The connection being accepted.
context
ConnectionContext
Contains the original HTTP upgrade Request, useful for reading auth tokens or query parameters to determine which tags to apply.
return
string[] | Promise<string[]>
Tags to associate with the connection. Retrievable later via connection.tags and filterable via getConnections(tag).
export class ChatServer extends Server {
  async getConnectionTags(connection: Connection, ctx: ConnectionContext) {
    const url = new URL(ctx.request.url);
    const room = url.searchParams.get("room") ?? "general";
    return [room];
  }
}

Instance methods

broadcast

broadcast(
  msg: string | ArrayBuffer | ArrayBufferView,
  without?: string[]
): void
Send a message to every currently connected client. Pass connection IDs in the optional without array to exclude specific connections from the broadcast — useful for excluding the sender.
msg
string | ArrayBuffer | ArrayBufferView
The message payload to send.
without
string[]
Optional list of connection IDs to skip. Connections whose id appears in this array will not receive the message.
onMessage(connection: Connection, message: WSMessage) {
  // Echo the message to everyone except the sender
  this.broadcast(message, [connection.id]);
}

getConnections

getConnections<TState = unknown>(tag?: string): Iterable<Connection<TState>>
Return an iterable of all currently connected WebSocket connections. Provide a tag string to return only connections that were assigned that tag by getConnectionTags.
tag
string
Optional tag to filter by. When omitted, all connections are returned.
return
Iterable<Connection<TState>>
An iterable of matching Connection objects, each typed with TState if provided.
// Send a targeted message to all connections in a specific room
for (const conn of this.getConnections("room:lobby")) {
  conn.send("Welcome to the lobby!");
}

getConnection

getConnection<TState = unknown>(id: string): Connection<TState> | undefined
Look up a single connection by its unique ID. Returns undefined if no connection with that ID is currently active.
id
string
The unique connection ID to look up.
return
Connection<TState> | undefined
The matching Connection, or undefined if not found.

sql

sql<T = Record<string, string | number | boolean | null>>(
  strings: TemplateStringsArray,
  ...values: (string | number | boolean | null)[]
): T[]
Execute a SQL query against the server’s built-in SQLite database (backed by Durable Object SQLite storage) using a tagged template literal. Returns an array of result rows typed as T.
const rows = this.sql<{ username: string }>`
  SELECT username FROM users WHERE active = ${true}
`;

Properties

name

get name(): string
The server’s name. Resolved from this.ctx.id.name — the native Durable Object ID name populated whenever the stub was addressed via idFromName() or getByName(). Available in every entry point including the constructor, onStart(), onAlarm(), and hibernating WebSocket handlers.
PartyServer also persists a __ps_name fallback record during initialization so that alarm handlers firing on stale on-disk alarm records from older workerd versions can still recover the name.Accessing .name on a DO addressed via idFromString() or newUniqueId() without a setName() bootstrap will throw.

ctx

ctx: DurableObjectState
The Durable Object context object, inherited from the DurableObject base class. Provides access to ctx.storage (Transactional Storage API), ctx.waitUntil(), and other runtime primitives.

env

env: Env
The Worker environment object, containing all bindings declared in wrangler.jsonc — KV namespaces, R2 buckets, AI bindings, other Durable Object namespaces, and so on.

Durable Object methods — do not override

These methods are implemented by PartyServer and must not be overridden in subclasses. Override the corresponding lifecycle hooks instead.
Overriding any of these methods will break PartyServer’s connection management, hibernation support, or initialization logic.

fetch

async fetch(request: Request): Promise<Response>
PartyServer overrides fetch to route WebSocket upgrade requests through onConnect and plain HTTP requests through onRequest. If you must implement fetch yourself (e.g. to intercept requests before any lifecycle methods run), call super.fetch(request) at the appropriate point to preserve lifecycle behavior.

alarm

async alarm(): Promise<void>
Ensures the server is initialized and then delegates to onAlarm(). Do not override — use onAlarm() instead.

webSocketMessage / webSocketClose / webSocketError

These three Durable Object hibernation API methods are overridden by PartyServer to dispatch to onMessage, onClose, and onError respectively. Do not implement them on your subclass.

Complete example

import { Server, type Connection, type ConnectionContext, type WSMessage } from "partyserver";

interface Env {
  MyServer: DurableObjectNamespace;
}

interface UserState {
  username: string;
}

export class MyServer extends Server<Env> {
  static options = { hibernate: true };

  async getConnectionTags(connection: Connection, ctx: ConnectionContext) {
    const url = new URL(ctx.request.url);
    return [url.searchParams.get("room") ?? "general"];
  }

  async onConnect(connection: Connection<UserState>, ctx: ConnectionContext) {
    const token = ctx.request.headers.get("Authorization");
    connection.setState({ username: await verifyToken(token) });
    this.broadcast(`${connection.state?.username} joined`);
  }

  onMessage(connection: Connection<UserState>, message: WSMessage) {
    this.broadcast(`${connection.state?.username}: ${message}`, [connection.id]);
  }

  onClose(connection: Connection<UserState>) {
    this.broadcast(`${connection.state?.username} left`);
  }
}

async function verifyToken(token: string | null): Promise<string> {
  // your auth logic here
  return token ?? "anonymous";
}

Build docs developers (and LLMs) love