Skip to content
cable
Esc
↑↓navigate↵open⌘Jpreview
On this page

Welcome

Type-safe RPC and durable realtime channels for TypeScript, with presence, permissions, and replay built in.

Define the contract once. The server and client use the same types for RPC and realtime events.

import { c } from "@cablejs/contract";
import { z } from "zod";

export const api = c.contract({
  profile: c.query({
    input: z.object({ userId: z.string() }),
    output: z.object({ name: z.string() }),
  }),
  chat: c.channel("chat.{roomId}", {
    server: { message: z.object({ author: z.string(), text: z.string() }) },
    client: { send: z.object({ text: z.string().min(1) }) },
  }),
});
import { createClient } from "@cablejs/client";
import { api } from "./api.js";

const client = createClient({ contract: api, url: "/_cable" });
const profile = await client.profile.query({ userId: "user-1" });
const room = client.chat({ roomId: "general" });
room.on("message", (message) => console.log(message.author, message.text));
await room.send({ text: `Hello from ${profile.name}` }, { ack: true });

The complete server setup, including the handler and channel host, is in Get started. The Cloudflare adapter guide covers deployment and bindings.

Start here

Choose your next guide

  • Authorization shows context refinement with public, protected, and admin procedures.
  • React adds cable to a React component tree.
  • Channels explains channel keys, events, presence, and history.
  • Cloudflare Durable Objects runs one channel host per Durable Object.

Was this page helpful?