hello-rivet-next: The End of the REST API for Real-Time Apps
How a bleeding-edge reference architecture uses the Actor model to replace event-driven boilerplate with fully typed, synchronized shared state.
- Rivet shifts frontend state management from request-response fetching to connecting directly to stateful actors.
- The architecture eliminates WebSocket boilerplate by handling pub/sub broadcasting automatically at the framework level.
- Passing the backend registry to the frontend creates an unbreakable type-safe contract for all real-time events.
The GUI Tax on Real-Time State
Next.js handles standard CRUD applications beautifully. You fetch data, render UI, and mutate state via server actions. But the moment an application requires real-time multiplayer features, the architectural complexity explodes.
Building live cursors, shared counters, or collaborative documents usually requires a massive amount of boilerplate. Developers are forced to manually orchestrate WebSockets, build custom event routers, and maintain complex Redux or Saga architectures just to keep clients in sync. This is the real-time tax.
Hiring Actors for the Frontend
The hello-rivet-next repository demonstrates a paradigm shift. It introduces the Rivetkit Actor model to the Next.js frontend. Instead of writing custom routing logic for every state mutation, developers define an Actor.
An Actor is a stateful entity that holds its own data and broadcasts changes automatically. When a client calls a method on an Actor, the framework handles the complex fan-out broadcasting to all connected clients. The mental model shifts from fetching data to connecting to a living instance.
The Source of Truth Contract
The technical meat of the project lives in registry.ts. This file defines the state object and its available actions. The true power unlocks when this registry is passed to the Next.js client.
By passing typeof registry to the frontend, Rivet creates an unbreakable, type-safe contract. Backend changes instantly flag frontend compilation errors, providing 100 percent end-to-end type safety for real-time events without requiring external generators like OpenAPI.
import { actor } from 'rivetkit';
export const counterActor = actor({
state: { count: 0 },
actions: {
increment: (c, amount: number) => {
c.state.count += amount;
c.broadcast('newCount', c.state.count);
}
}
});
Multiplayer by Default
On the client side, consuming this state is remarkably simple. The useActor hook allows developers to connect to an isolated instance using a unique key.
By simply changing the key array (e.g., ["room-123"]), developers spin up isolated, real-time rooms with a single line of code. The frontend interacts with remote state exactly as it would local React state.
| Feature | Traditional REST + WebSocket | Rivet Actor Model |
|---|---|---|
| State Location | Client Cache + Database | In-Memory Actor |
| Communication | Manual Fetch/Push & Socket Listeners | Automated Pub/Sub Sync |
| Type Safety | Requires external generators (OpenAPI) | Native TypeScript inference |
| Routing | Individual endpoint per action | Single wildcard API bridge |