SQLite
Every Rivet Actor has its own embedded SQLite database.
SQLite is built into Rivet Actors: every Actor owns a database that lives and moves with it, so there is nothing to provision or connect. Declare db on the Actor, create your tables in onMigrate, and run SQL from any action with c.db.execute(...).
import { actor, setup } from "rivetkit";
import { db } from "rivetkit/db";
export const todoList = actor({
db: db({
onMigrate: async (db) => {
await db.execute(`
CREATE TABLE IF NOT EXISTS todos (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL
);
`);
await db.execute(`
CREATE TABLE IF NOT EXISTS comments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
todo_id INTEGER NOT NULL,
body TEXT NOT NULL,
FOREIGN KEY(todo_id) REFERENCES todos(id)
);
`);
},
}),
actions: {
addTodo: async (c, title: string) => {
await c.db.execute("INSERT INTO todos (title) VALUES (?)", title);
},
addComment: async (c, todoId: number, body: string) => {
await c.db.execute(
"INSERT INTO comments (todo_id, body) VALUES (?, ?)",
todoId,
body,
);
},
getTodos: async (c) => {
return (await c.db.execute(
"SELECT id, title FROM todos ORDER BY id DESC",
)) as {
id: number;
title: string;
}[];
},
},
});
export const registry = setup({ use: { todoList } });
registry.start();
import { createClient } from "rivetkit/client";
import type { registry } from "./index";
const client = createClient<typeof registry>("http://localhost:6420");
const handle = client.todoList.getOrCreate(["main"]);
await handle.addTodo("Write SQLite docs");
await handle.addTodo("Ship docs update");
const todos = await handle.getTodos();
console.log(todos);
Each Actor’s database is isolated from every other Actor’s, and its rows persist across sleep, crashes, and upgrades like the rest of the Actor’s state. Keep one Actor per thing you would otherwise give its own table, such as a user, a document, or an agent conversation, so each database stays small and close to the code that uses it.
Use Drizzle when you want a typed query builder over the same database. For a hosted SQLite-compatible database you reach over the network, see Turso.
The SQLite feature page covers queries, transactions, migrations, and limits.