Introduction
A local-first sync engine for React. Define queries and mutations once, run them on the client or the server.
// valet/todos.ts
import { defineQuery, defineMutation, v } from './_generated/valet/api'
export const list = defineQuery({
args: {},
execution: 'local',
handler: async (ctx) => {
return ctx.db
.query('todos')
.filter((q) => q.eq('completed', false))
.order('createdAt', 'desc')
.collect()
},
})
export const create = defineMutation({
args: { title: v.string() },
handler: async (ctx, args) => {
return ctx.db.insert('todos', {
title: args.title,
completed: false,
})
},
})Valet is a sync engine for React. Define your queries and mutations once, then choose an execution mode: local for instant reads against client-side SQLite, or server for full-dataset access. Offline mutations queue automatically and rebase against fresh server state on reconnect.
Local queries run against a SQLite replica in the browser, so reads are instant -- no loading spinners, no network round-trips. Mutations are server-authoritative but apply optimistic updates on the client immediately. When a client goes offline, mutations queue and replay deterministically on reconnect: Valet captures crypto.randomUUID(), Math.random(), and Date.now() during the first execution so replayed handlers produce identical results. A type-safe codegen step turns your schema into ready-to-use React hooks.
Get started
Quickstart
Install, define a schema, connect to React in 5 minutes.
Why Valet
How Valet compares to Convex, InstantDB, Zero, and others.
Learn
Schema
Tables, validators, indexes, and codegen.
Queries
defineQuery, execution modes, filters, and pagination.
Mutations
defineMutation, database writes, and optimistic updates.
Sync Rules
Control which documents sync to which users.