Lunora is a type-safe, real-time backend framework on Cloudflare Workers and Durable Objects with a Vite-first developer experience. Define a schema and write query, mutation, and action functions on the server; the client gets end-to-end typed data with live subscriptions, optimistic updates, and an offline queue — types sync from server to client automatically via codegen.
Realtime backends, in a few lines of code.
Define a schema, write a function — Lunora gives you a typed, live-syncing API on Cloudflare's edge. No glue code, no infrastructure to manage.
1import { mutation, query, v } from 'lunorash/server';2 3export const list = query.query(4 async ({ ctx }) => ctx.db.query('todos').collect(),5);6 7export const add = mutation8 .input({ text: v.string() })9 .mutation(async ({ ctx, args }) =>10 ctx.db.insert('todos', { ...args, done: false }),11 );12 13export const toggle = mutation14 .input({ id: v.id('todos'), done: v.boolean() })15 .mutation(async ({ ctx, args }) =>16 ctx.db.patch(args.id, { done: args.done }),17 );| # | _id id | _creationTime number | text string | done boolean |
|---|---|---|---|---|
| 1 | k00044zn | 06/01 00:00:00 | "Ship the launch post" | false |
| 2 | k000568i | 06/01 01:00:00 | "Review the pull request" | true |
| 3 | k00067hd | 06/01 02:00:00 | "Walk the dog" | false |
Everything you need to ship realtime
Realtime, storage, types, and a studio — typed and edge-native by default.
Everything is code
Schema, queries, and mutations in pure TypeScript — codegen keeps server and client in lockstep.
export default defineSchema({ todos: defineTable({ text: v.string(), done: v.boolean(), }),});Realtime by default
Queries are subscriptions. Every mutation pushes live updates to all clients — with optimistic writes and an offline queue.
// subscribes once, re-renders on every changeconst todos = useQuery(api.todos.list);const add = useMutation(api.todos.add);Edge-native & sharded
State lives in SQLite-backed Durable Objects at the edge. Shard by key, or go global to replicate reads across regions.
export const messages = defineTable({ roomId: v.string(), body: v.string(),}).shardBy('roomId');Studio included
A local admin UI for schema, data, SQL, logs, and time-travel ships with every app — running against your live edge database.

End-to-end typed
Types flow from server functions to the client via codegen. Rename a field and the client stops compiling.
export type Todo = { _id: Id<'todos'>; text: string; done: boolean;};Rewind your data
Every shard is a SQLite database you can rewind — restore to any moment in the last 30 days, with no extra infrastructure.

Define. Write. Ship.
From a schema to a live, globally-synced backend in three steps.
1import { defineSchema, defineTable, v } from 'lunorash/server';2 3export default defineSchema({4 todos: defineTable({5 text: v.string(),6 done: v.boolean(),7 }),8});Works with your entire stack
One framework, every frontend — Lunora ships live adapters for React, Vue, Svelte, Solid, Astro, TanStack, Nuxt, and Analog, powered by a Vite-first dev experience.
Open source, built together
Lunora is open source and built in the open. Star the repo, file an issue, or send a pull request — every contribution keeps it moving.
Ready to ship realtime apps?
Open source, deployed to your own Cloudflare account, with no infrastructure to manage.
Start building