React Quickstart
Build a realtime React application with Rivet Actors, subscribe to events, and invoke typed actions through the React client.
Steps
Add Rivet Skill to Coding Agent (Optional)
If you’re using an AI coding assistant (like Claude Code, Cursor, Windsurf, etc.), add Rivet skills for enhanced development assistance:
npx skills add rivet-dev/skills
Create a Project
Create an empty project and install RivetKit, React, and Vite:
mkdir my-app
cd my-app
npm init -y
npm pkg set type=module
npm install rivetkit @rivetkit/react react react-dom
npm install -D vite @vitejs/plugin-react tsx
The finished project has this layout:
my-app/
backend/index.ts
frontend/Counter.tsx
frontend/main.tsx
index.html
vite.config.ts
Create Backend Actor and Start Server
Create your actor registry on the backend and start the server:
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();
Create React Frontend
Create a component that connects to the actor, then mount it:
import { createRivetKit } from "@rivetkit/react";
import { useState } from "react";
import type { registry } from "../backend/index";
const { useActor } = createRivetKit<typeof registry>("http://localhost:6420");
export function Counter() {
const [count, setCount] = useState(0);
// Get or create a counter actor for the key "my-counter"
const counter = useActor({
name: "counter",
key: ["my-counter"],
});
// Listen to realtime events
counter.useEvent("newCount", (x: number) => setCount(x));
const increment = async () => {
// Call actions
await counter.connection?.increment(1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}
Create the HTML page that loads it:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Rivet Counter</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/frontend/main.tsx"></script>
</body>
</html>
For detailed information about the React client API, see the React Client API Reference.
Setup Vite Configuration
Configure Vite for development:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
server: {
port: 5173,
},
})
Run Your Application
Start both the backend and frontend:
Terminal 1: Start the backend
npx tsx --watch backend/index.ts
bun --watch backend/index.ts
deno run --allow-net --allow-read --allow-env --watch backend/index.ts
Terminal 2: Start the frontend
npx vite
Open http://localhost:5173 in your browser. Try opening multiple tabs to see realtime sync in action.
Deploy
In development, Rivet runs a local control plane for you and keeps Actor data on your machine.
To scale Rivet in production, pick how much of it you want to run yourself:
Fully managed
Bring your own compute
Full self-hosting
If you are running your own nodes, follow the guide for your hosting provider:
Configuration Options
- Server Setup: Different ways to run your server with serve(), handler(), or framework adapters.
- Clients: Connect to Actors from JavaScript, React, or other platforms.
- Authentication: Secure Actor connections with custom authentication logic.
- CORS: Configure origin restrictions to secure your Actors from unauthorized access.
- Logging: Configure logging output for debugging and monitoring.
- Nodes & Node Pools: Run your app as long-lived nodes grouped into node pools.