Everything is code
Schema, queries, and mutations in pure TypeScript — codegen keeps server and client in lockstep.
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.
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.
Available for React · Vue · Svelte · Solid
Realtime, storage, types, and a studio — with no glue code between them.
Schema, queries, and mutations in pure TypeScript — codegen keeps server and client in lockstep.
Queries are subscriptions. Every mutation pushes live updates to all clients — with optimistic writes and an offline queue.
State lives in SQLite-backed Durable Objects at the edge. Shard by key, or go global to replicate reads across regions.
A local admin UI for schema, data, SQL, logs, and time-travel ships with every app — running against your live edge database.
Types flow from server functions to the client via codegen. Rename a field and the client stops compiling.
Every shard is a SQLite database you can rewind — restore to any moment in the last 30 days, with no extra infrastructure.
A schema, a function, and a component — the whole round trip in one screen.
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 |
Each one is a whole app built around a different part of the framework. Deploy runs it on your own Cloudflare account — it clones the repo, provisions the bindings its wrangler.jsonc declares, and asks for any secret it needs.
Drag-and-drop board, live for everyone looking at it.
Fractional index ordering, server-resolved drops, multi-query optimistic updates
No sign-in — anyone with the URL can use it
Channels, presence, search, and file uploads.
A shard per channel, all three data tiers, authorizeShard, signed R2 uploads
Requires sign-in
Multiplayer chess with lobbies, spectators and Elo.
Server-authoritative rules, serialized mutations as a game rule, in-transaction settlement
Requires sign-in
Public feature-request board with AI summaries.
Unique index as a constraint, denormalised counters, ctx.ai from an action
No sign-in — anyone with the URL can use it
SSR that hands over to a live socket.
Route loaders sharing a cache key with useQuery, one worker for SSR and RPC
No sign-in — anyone with the URL can use it
Auth, payments, push notifications, an offline outbox, semantic search, shared cursors, Expo, and the smallest possible CRUD round-trip.
From a schema to a live, globally-synced backend.
1import { defineSchema, defineTable, v } from 'lunorash/server';2 3export default defineSchema({4 todos: defineTable({5 text: v.string(),6 done: v.boolean(),7 }),8});A local admin UI ships with every app and runs against your live edge database. No separate deploy, no read-only mirror.

Every table, column, index, and relation, read from your schema.
Opt-in packages for auth, payments, email, AI, storage, and jobs — typed onto your ctx.
Deployed to your own Cloudflare account.
A customizable auth system built on Better Auth — D1-backed, or bring your own store.
Provider-agnostic payments with a Stripe-first adapter and webhook sync — Polar included.
Beautiful, TSX-templated transactional email. Integrate Resend, or use your own SMTP.
Workers AI on the Vercel AI SDK — provider-agnostic models wired onto every action ctx.
Typed Cloudflare binding facades in one install — storage and data plumbing on ctx.
Durable background work: cron triggers, delayed jobs, queues, and multi-step workflows.
Bring your own Postgres or MySQL over Cloudflare Hyperdrive — a driver-agnostic ctx.sql.
Ship with confidence — an in-memory harness, schema advisors, and deterministic seeding.
Start with the adapter built for your project.
Same reactive, typed model as the best of them. The difference is where it runs and who sends the bill.
The full matrix, including where they win, is on the comparison pages.
| Capability | Lunora | Convex | Supabase | Firebase |
|---|---|---|---|---|
| End-to-end TypeScript types | Yes, typed functions | Yes | Generated schema types | Manual converters (schemaless) |
| Reactive queries by default | Yes, reactive queries | Yes | No, change-feed / broadcast API | Yes, onSnapshot listeners |
| Edge / global by default | Yes, Cloudflare edge + DO | No, regional AWS (US, EU) | Regional Postgres + read replicas | Google multi-region |
| Self-host with no servers to run | Yes, serverless Workers | No, Rust server + SQL DB | No, Docker Compose stack | No self-host |
| ≈$0 at idle, no forced pause | ≈$0, no forced pause | Free tier on Convex's AWS | Free tier pauses after ~7 days idle | Free tier; per-op billing can spike |
Including the ones with awkward answers.
No. Lunora is alpha and the API still breaks between releases. Every package is published under a 1.0.0-alpha version and pre-release branches drop old code paths rather than keeping shims. Build side projects and internal tools on it today; wait for 1.0 before it carries revenue.
Your own Cloudflare account. Lunora deploys as Workers and Durable Objects that you own, so your data sits in your account and your bill comes from Cloudflare. There is no Lunora-operated cloud to migrate off, because there is no Lunora-operated cloud.
Yes, and self-hosting is the only mode. It is not a degraded tier of a paid product. The framework is FSL-1.1-Apache-2.0: source-available now, and each release converts to Apache-2.0 on a fixed schedule.
State lives in SQLite-backed Durable Objects at the edge. A single Durable Object per app is the default and is enough for most projects; you opt into sharding by user, tenant, or room when you need it, and into global replication for low-latency reads.
React, Vue, Svelte, Solid, Astro, TanStack, Nuxt, and Analog have live adapters, plus React Native and Expo. The client is framework-agnostic underneath, so a framework without an adapter still works, just without the framework-specific hooks.
Self-hosted, you pay Cloudflare directly at their published rates and nothing else. Durable Objects idle at roughly nothing and nothing forces a project to pause, so an unvisited project costs about what it did last month.
Nothing about Lunora is a black box. Read it, fork it, or send the fix yourself.
Every contribution is reviewed. Small fixes are welcome.
Labelled and scoped so a first PR is not a research project.
The roadmap moves in public.
Open source, deployed to your own Cloudflare account, with no infrastructure to manage.
Start building