with one click
rivetkit-client-react
// RivetKit React client guidance. Use for React apps that connect to Rivet Actors with @rivetkit/react, create hooks with createRivetKit, or manage realtime state with useActor.
// RivetKit React client guidance. Use for React apps that connect to Rivet Actors with @rivetkit/react, create hooks with createRivetKit, or manage realtime state with useActor.
| name | rivetkit-client-react |
| description | RivetKit React client guidance. Use for React apps that connect to Rivet Actors with @rivetkit/react, create hooks with createRivetKit, or manage realtime state with useActor. |
Use this skill when building React apps that connect to Rivet Actors with @rivetkit/react.
npm install @rivetkit/react@2.3.0-rc.5
createRivetKit() and connect with useActor().try/catch unless absolutely needed.catch is used, handle the error explicitly, at minimum by logging it.See the React quickstart guide for getting started.
import { createRivetKit } from "@rivetkit/react";
import type { registry } from "./index";
const { useActor } = createRivetKit<typeof registry>({
endpoint: "https://my-namespace:pk_...@api.rivet.dev",
});
function Counter() {
const { connection, connStatus } = useActor({ name: "counter", key: ["my-counter"] });
if (connStatus !== "connected" || !connection) return <div>Connecting...</div>;
return <button onClick={() => connection.increment(1)}>+</button>;
}
import { actor, setup } from "rivetkit";
export const counter = actor({
state: { count: 0 },
actions: {
increment: (c, x: number) => {
c.state.count += x;
c.broadcast("newCount", c.state.count);
return c.state.count;
},
},
});
export const registry = setup({
use: { counter },
});
registry.start();
import { createRivetKit } from "@rivetkit/react";
const { useActor } = createRivetKit();
function Counter() {
const counter = useActor({ name: "counter", key: ["my-counter"] });
const increment = async () => {
await counter.connection?.increment(1);
};
return <button onClick={increment}>+</button>;
}
// Stateless: use createClient for one-off calls (SSR or utilities)
import { createClient } from "rivetkit/client";
const client = createClient();
await client.counter.getOrCreate(["my-counter"]).increment(1);
import { createRivetKit } from "@rivetkit/react";
import { createClient } from "rivetkit/client";
const { useActor } = createRivetKit();
function ChatRoom() {
const room = useActor({ name: "chatRoom", key: ["room-42"] });
return <div>{room.connStatus}</div>;
}
// For get/getOrCreate/create/getForId, use createClient
const client = createClient();
const handle = client.chatRoom.getOrCreate(["room-42"]);
const existing = client.chatRoom.get(["room-42"]);
const created = await client.game.create(["game-1"], { input: { mode: "ranked" } });
const byId = client.chatRoom.getForId("actor-id");
const resolvedId = await handle.resolve();
import { createRivetKit } from "@rivetkit/react";
const { useActor } = createRivetKit();
function Chat() {
const chat = useActor({
name: "chatRoom",
key: ["general"],
params: { authToken: "jwt-token-here" },
});
return <div>{chat.connStatus}</div>;
}
import { createRivetKit } from "@rivetkit/react";
const { useActor } = createRivetKit();
function Chat() {
const chat = useActor({ name: "chatRoom", key: ["general"] });
chat.useEvent("message", (msg) => {
console.log("message:", msg);
});
return null;
}
import { createRivetKit } from "@rivetkit/react";
const { useActor } = createRivetKit();
function CounterStatus() {
const actor = useActor({ name: "counter", key: ["my-counter"] });
if (actor.connStatus === "connected") {
console.log("connected");
}
if (actor.error) {
console.error(actor.error);
}
return null;
}
Use the JavaScript client for raw HTTP and WebSocket access:
import { createClient } from "rivetkit/client";
const client = createClient();
const handle = client.chatRoom.getOrCreate(["general"]);
const response = await handle.fetch("history");
const history = await response.json();
const ws = await handle.webSocket("stream");
ws.addEventListener("message", (event) => {
console.log("message:", event.data);
});
ws.send("hello");
Use the JavaScript client on your backend (Node.js/Bun). See the JavaScript client docs.
import { ActorError } from "rivetkit/client";
import { createRivetKit } from "@rivetkit/react";
const { useActor } = createRivetKit();
function Profile() {
const actor = useActor({ name: "user", key: ["user-123"] });
const updateUsername = async () => {
try {
await actor.connection?.updateUsername("ab");
} catch (error) {
if (error instanceof ActorError) {
console.log(error.code, error.metadata);
}
}
};
return <button onClick={updateUsername}>Update</button>;
}
Keys uniquely identify actor instances. Use compound keys (arrays) for hierarchical addressing:
import { createRivetKit } from "@rivetkit/react";
import type { registry } from "./index";
const { useActor } = createRivetKit<typeof registry>("http://localhost:6420");
function ChatRoom() {
const room = useActor({ name: "chatRoom", key: ["org-acme", "general"] });
return <div>{room.connStatus}</div>;
}
import { actor, setup } from "rivetkit";
export const chatRoom = actor({
state: { messages: [] as string[] },
actions: {
getRoomInfo: (c) => ({ org: c.key[0], room: c.key[1] }),
},
});
export const registry = setup({
use: { chatRoom },
});
registry.start();
Don't build keys with string interpolation like "org:${userId}" when userId contains user data. Use arrays instead to prevent key injection attacks.
createRivetKit() (and the underlying createClient() instance) automatically read:
RIVET_ENDPOINTRIVET_NAMESPACERIVET_TOKENRIVET_RUNNERDefaults to http://localhost:6420 when unset. RivetKit runs on port 6420 by default.
Endpoints support URL auth syntax:
https://namespace:token@api.rivet.dev
You can also pass the endpoint without auth and provide RIVET_NAMESPACE and RIVET_TOKEN separately. For serverless deployments, use your app's /api/rivet URL. See Endpoints for details.
Package: @rivetkit/react
createRivetKit - Create hooks for ReactuseActor - Hook for actor instancesIf you need more about Rivet Actors, registries, or server-side RivetKit, add the main skill:
npx skills add rivet-dev/skills
Then use the rivetkit skill for backend guidance.
Pragmatic patterns for building multiplayer games: matchmaking, tick loops, realtime state, interest management, and validation.
RivetKit JavaScript client guidance. Use for browser, Node.js, or Bun clients that connect to Rivet Actors with rivetkit/client, create clients, call actions, or manage connections.
RivetKit Swift client guidance. Use for Swift clients that connect to Rivet Actors with RivetKitClient, create actor handles, call actions, or manage connections.
RivetKit SwiftUI client guidance. Use for SwiftUI apps that connect to Rivet Actors with RivetKitSwiftUI, @Actor, rivetKit view modifiers, and SwiftUI bindings.
RivetKit backend and Rivet Actor runtime guidance. Use for building, modifying, debugging, or testing Rivet Actors, registries, serverless/runner modes, deployment, or actor-based workflows.
Deploy, configure, and integrate Sandbox Agent - a universal API for orchestrating AI coding agents (Claude Code, Codex, OpenCode, Amp) in sandboxed environments. Use when setting up sandbox-agent server locally or in cloud sandboxes (E2B, Daytona, Docker), creating and managing agent sessions via SDK or API, streaming agent events and handling human-in-the-loop interactions, building chat UIs for coding agents, or understanding the universal schema for agent responses.