Todo Example

This capsule shows the smallest useful Lakebed app pattern: authenticated per-user data with server-owned mutations.

What It Shows

Server Pattern

queries: {
  todos: query(async (ctx) =>
    ctx.db.todos
      .withIndex("by_owner", (q) => q.eq("ownerId", ctx.auth.userId))
      .order("desc")
      .collect()
  )
}

Use this pattern whenever rows belong to a single user. The client should not receive rows it does not own.

For mutations, fetch the row and check ownership before changing it:

const todo = await ctx.db.todos.get(id);
if (!todo || todo.ownerId !== ctx.auth.userId) {
  return;
}

await ctx.db.todos.update(id, { done });

Run It

Run the checked-in example:

npx lakebed auth as alice
npx lakebed dev examples/todo

Open:

http://localhost:3000

To compare two users, open:

http://localhost:3000/?lakebed_guest=alice
http://localhost:3000/?lakebed_guest=bob

Then inspect state:

npx lakebed db dump --port 3000
npx lakebed logs --port 3000