The open-source alternative to Durable Objects
Rivet Actors is a library that provides durable state, realtime, and scalability.
Easily self-hostable and works with your infrastructure.
Reconsider What Your Backend Can Do
Build powerful applications with Rivet Actors
import { actor } from "rivetkit";
import { generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
export type Message = {
role: "user" | "assistant";
content: string;
timestamp: number;
}
const aiAgent = actor({
// State is automatically persisted
state: {
messages: [] as Message[]
},
actions: {
// Get conversation history
getMessages: (c) => c.state.messages,
// Send a message to the AI and get a response
sendMessage: async (c, userMessage: string) => {
// Add user message to conversation
const userMsg: Message = {
role: "user",
content: userMessage,
timestamp: Date.now()
};
c.state.messages.push(userMsg);
// Generate AI response using Vercel AI SDK
const { text } = await generateText({
model: openai("o3-mini"),
prompt: userMessage,
messages: c.state.messages,
});
// Add AI response to conversation
const assistantMsg: Message = {
role: "assistant",
content: text,
timestamp: Date.now()
};
c.state.messages.push(assistantMsg);
// Broadcast to all connected clients
c.broadcast("messageReceived", assistantMsg);
return assistantMsg;
},
}
});
export default aiAgent;
import { createClient } from "rivetkit/client";
import { createReactRivetKit } from "@rivetkit/react";
import { useState, useEffect } from "react";
const client = createClient<App>("http://localhost:8080");
const { useActor, useActorEvent } = createReactRivetKit(client);
export function AIAssistant() {
const [{ actor }] = useActor("aiAgent", {
tags: { conversationId: "default" }
});
const [messages, setMessages] = useState<Message[]>([]);
const [input, setInput] = useState("");
const [isLoading, setIsLoading] = useState(false);
// Load initial messages
useEffect(() => {
if (actor) {
actor.getMessages().then(setMessages);
}
}, [actor]);
// Listen for real-time messages
useActorEvent({ actor, event: "messageReceived" }, (message) => {
setMessages(prev => [...prev, message as Message]);
setIsLoading(false);
});
const handleSendMessage = async () => {
if (actor && input.trim()) {
setIsLoading(true);
// Add user message to UI immediately
const userMessage = { role: "user", content: input };
setMessages(prev => [...prev, userMessage]);
// Send to actor
await actor.sendMessage(input);
setInput("");
}
};
return (
<div className="ai-chat">
<div className="messages">
{messages.map((msg, i) => (
<div key={i} className={`message ${msg.role}`}>
<div className="avatar">
{msg.role === "user" ? "๐ค" : "๐ค"}
</div>
<div className="content">{msg.content}</div>
</div>
))}
</div>
<div className="input-area">
<input
value={input}
onChange={e => setInput(e.target.value)}
onKeyPress={e => e.key === "Enter" && handleSendMessage()}
placeholder="Ask the AI assistant..."
disabled={isLoading}
/>
<button
onClick={handleSendMessage}
disabled={isLoading || !input.trim()}
>
Send
</button>
</div>
</div>
);
}
Built for Modern Applications
Everything you need to build fast, scalable, and real-time applications without the complexity.
Long-Lived, Stateful Compute
Each unit of compute is like a tiny server that remembers things between requests โ no need to re-fetch data from a database or worry about timeouts. Like AWS Lambda, but with memory and no timeouts.
DocumentationBlazing-Fast Reads & Writes
State is stored on the same machine as your compute, so reads and writes are ultra-fast. No database round trips, no latency spikes.
DocumentationRealtime, Made Simple
Update state and broadcast changes in realtime with WebSockets or SSE. No external pub/sub systems, no polling โ just built-in low-latency events.
DocumentationStore Data Near Your Users
Your state lives close to your users on the edge โ not in a faraway data center โ so every interaction feels instant. (Not all platforms supported.)
DocumentationInfinitely Scalable
Automatically scale from zero to millions of concurrent actors. Pay only for what you use with instant scaling and no cold starts.
DocumentationFault Tolerant
Built-in error handling and recovery. Actors automatically restart on failure while preserving state integrity and continuing operations.
DocumentationType Safety
End-to-end TypeScript safety between clients and actors with full type inference and compile-time checking.
DocumentationRuns Anywhere
Deploy Rivet Actors anywhere - from serverless platforms to your own infrastructure with Rivet's flexible runtime options.
Don't see the runtime you want? Add your own.
Works With Your Tools
Seamlessly integrate Rivet with your favorite frameworks, languages, and tools.
Don't see what you need? Request an integration.
Supercharged Local Development with the Studio
Like Postman, but for all of your stateful serverless needs.
View and edit your actor state in real-time as messages are sent and processed
Debug your actor in real-time - call actions, subscribe to events, and interact directly with your code
Monitor active connections with state and parameters for each client
See code changes instantly without restarting - modify and test on the fly
Join the Community
Join thousands of developers building with Rivet Actors today