Getting Started
Zocket is strongest when your product is made of live entities clients interact with directly: chats, agents, sessions, rooms, workflows, or collaborative objects.
This quickstart uses a chat room, but the mental model is the same for an AI agent thread, a multiplayer lobby, or a support conversation: define the actor, give it typed methods and state, then let clients call it and subscribe to it.
Installation
Section titled “Installation”bun add @zocket/core @zocket/server @zocket/client zodnpm install @zocket/core @zocket/server @zocket/client zodFor React integration, also add @zocket/react:
bun add @zocket/react1. Define a Live Actor
Section titled “1. Define a Live Actor”Actors are stateful units with identity, typed methods, state, events, and lifecycle hooks.
import { z } from "zod";import { actor, createApp } from "@zocket/core";
const ChatRoom = actor({ state: z.object({ messages: z.array(z.object({ from: z.string(), text: z.string(), })).default([]), }),
methods: { sendMessage: { input: z.object({ from: z.string(), text: z.string() }), handler: ({ state, input }) => { state.messages.push(input); }, }, },});
export const app = createApp({ actors: { chat: ChatRoom } });2. Serve the Actor
Section titled “2. Serve the Actor”import { serve } from "@zocket/server/bun";import { app } from "./chat";
const server = serve(app, { port: 3000 });console.log(`Zocket on ws://localhost:${server.port}`);3. Connect a Client to It
Section titled “3. Connect a Client to It”import { createClient } from "@zocket/client";import type { app } from "./chat";
const client = createClient<typeof app>({ url: "ws://localhost:3000" });
// Get a typed handle for a specific live actor instanceconst room = client.chat("general");
// Call methods — fully typedawait room.sendMessage({ from: "Alice", text: "Hello!" });
// Subscribe to state changesroom.state.subscribe((state) => { console.log("Messages:", state.messages);});
// Clean up when doneroom.meta.dispose();4. Use with React
Section titled “4. Use with React”import { createClient } from "@zocket/client";import { createZocketReact } from "@zocket/react";import type { app } from "./chat";
export const client = createClient<typeof app>({ url: "ws://localhost:3000" });export const { ZocketProvider, useActor, useActorState } = createZocketReact<typeof app>();import { ZocketProvider, useActor, useActorState, client } from "./zocket";
function Chat() { const room = useActor("chat", "general"); const messages = useActorState(room, (s) => s.messages);
return ( <ul> {messages?.map((m, i) => ( <li key={i}>{m.from}: {m.text}</li> ))} </ul> );}
export function App() { return ( <ZocketProvider client={client}> <Chat /> </ZocketProvider> );}Next Steps
Section titled “Next Steps”- Use Cases — where Zocket fits best: chats, agents, workflows, rooms, and collaborative state
- Motivation — why Zocket is structured this way
- Why Actors — the conceptual model behind actor-based realtime code
- Actors — full API for state, methods, events, and lifecycle hooks
- Middleware — auth, context enrichment, gating
- React Hooks —
useActor,useActorState,useEvent - Multiplayer Draw — complete example walkthrough