Skip to content

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.

Open source / FSL-1.1-Apache-2.0Alpha

Lunora.
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.

Available for React · Vue · Svelte · Solid

Make your agent a Lunora expertWorks with any model, any agent, any editor
Built on the Cloudflare Developer Platform
  • Workers
  • Durable Objects
  • D1
  • R2
  • Queues
  • Workflows
  • Vectorize
  • Hyperdrive
  • Workers AI
Open source
FSL-1.1-Apache-2.0, deployed to your own Cloudflare account.
Realtime
Every query is a subscription; mutations push to all clients.
Typed end to end
Codegen keeps server and client in lockstep, or it stops compiling.
Edge native
SQLite-backed Durable Objects, shardable by user, tenant, or room.
Vite first
One dev server for the frontend, the backend, and the studio.
Framework

Everything you need to ship realtime

Realtime, storage, types, and a studio — with no glue code between them.

Everything is code

Schema, queries, and mutations in pure TypeScript — codegen keeps server and client in lockstep.

defineSchema() -> _generated/

Realtime by default

Queries are subscriptions. Every mutation pushes live updates to all clients — with optimistic writes and an offline queue.

  • useQuery()
  • useMutation()
  • live subscriptions
  • offline queue

Edge-native & sharded

State lives in SQLite-backed Durable Objects at the edge. Shard by key, or go global to replicate reads across regions.

  • .shardBy('roomId')
  • .global()
  • SQLite DO

Studio included

A local admin UI for schema, data, SQL, logs, and time-travel ships with every app — running against your live edge database.

lunora dev -> :5173/studio

End-to-end typed

Types flow from server functions to the client via codegen. Rename a field and the client stops compiling.

  • Id<'todos'>
  • Doc<'todos'>
  • _generated/

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.

  • restore --at 30d
  • point-in-time
  • 30-day window
Playground

Copy, paste, ship.

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 = mutation
8 .input({ text: v.string() })
9 .mutation(async ({ ctx, args }) =>
10 ctx.db.insert('todos', { ...args, done: false }),
11 );
12
13export const toggle = mutation
14 .input({ id: v.id('todos'), done: v.boolean() })
15 .mutation(async ({ ctx, args }) =>
16 ctx.db.patch(args.id, { done: args.done }),
17 );
app · todoslive
studio · todos3 docs
#_id id_creationTime numbertext stringdone boolean
1k00044zn06/01 00:00:00"Ship the launch post"false
2k000568i06/01 01:00:00"Review the pull request"true
3k00067hd06/01 02:00:00"Walk the dog"false
Examples

Or start from a working app

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.

Kanban board

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

Team chat

Channels, presence, search, and file uploads.

A shard per channel, all three data tiers, authorizeShard, signed R2 uploads

Requires sign-in

Chess

Multiplayer chess with lobbies, spectators and Elo.

Server-authoritative rules, serialized mutations as a game rule, in-transaction settlement

Requires sign-in

Feedback board

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

TanStack Start

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

Eight more

Auth, payments, push notifications, an offline outbox, semantic search, shared cursors, Expo, and the smallest possible CRUD round-trip.

All examples
How it works

Define. Write. Ship.

From a schema to a live, globally-synced backend.

lunora/schema.ts
1import { defineSchema, defineTable, v } from 'lunorash/server';
2
3export default defineSchema({
4 todos: defineTable({
5 text: v.string(),
6 done: v.boolean(),
7 }),
8});
Studio

Look at your backend.

A local admin UI ships with every app and runs against your live edge database. No separate deploy, no read-only mirror.

Lunora Studio — Schema

Every table, column, index, and relation, read from your schema.

Add-ons

Everything a real app needs

Opt-in packages for auth, payments, email, AI, storage, and jobs — typed onto your ctx.

Deployed to your own Cloudflare account.

Auth

A customizable auth system built on Better Auth — D1-backed, or bring your own store.

  • Email & password
  • Social login (OAuth)
  • Magic links
  • 2FA & passkeys
  • Organizations & RBAC
  • Email verification
  • SSO / OIDC

Payments & Billing

Provider-agnostic payments with a Stripe-first adapter and webhook sync — Polar included.

  • Subscriptions
  • Webhook state sync
  • Entitlements
  • Metered & usage-based
  • Idempotency
  • Money helpers

Transactional Email

Beautiful, TSX-templated transactional email. Integrate Resend, or use your own SMTP.

  • TSX templates
  • Queue-backed sends
  • Resend adapter
  • Custom SMTP
  • Mail-catcher testing

AI

Workers AI on the Vercel AI SDK — provider-agnostic models wired onto every action ctx.

  • Workers AI models
  • Provider-agnostic
  • generateText / streamText
  • Embeddings
  • Typed tool calls

Storage & Bindings

Typed Cloudflare binding facades in one install — storage and data plumbing on ctx.

  • R2 typed buckets & signed URLs
  • Workers KV
  • Cloudflare Images
  • Vectorize
  • Analytics Engine

Background Jobs

Durable background work: cron triggers, delayed jobs, queues, and multi-step workflows.

  • Cron triggers
  • runAfter / runAt
  • Durable Workflows
  • Typed queues
  • Reusable steps

Bring-your-own DB

Bring your own Postgres or MySQL over Cloudflare Hyperdrive — a driver-agnostic ctx.sql.

  • PostgreSQL & MySQL
  • Cloudflare Hyperdrive
  • node-postgres / postgres.js
  • mysql2
  • Connection pooling

Testing & Advisors

Ship with confidence — an in-memory harness, schema advisors, and deterministic seeding.

  • In-memory test harness
  • Vitest
  • Schema & query advisors
  • Deterministic seeding
  • GitHub Actions
Compare

Where Lunora differs

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.

CapabilityLunoraConvexSupabaseFirebase
End-to-end TypeScript typesYes, typed functionsYesGenerated schema typesManual converters (schemaless)
Reactive queries by defaultYes, reactive queriesYesNo, change-feed / broadcast APIYes, onSnapshot listeners
Edge / global by defaultYes, Cloudflare edge + DONo, regional AWS (US, EU)Regional Postgres + read replicasGoogle multi-region
Self-host with no servers to runYes, serverless WorkersNo, Rust server + SQL DBNo, Docker Compose stackNo self-host
≈$0 at idle, no forced pause≈$0, no forced pauseFree tier on Convex's AWSFree tier pauses after ~7 days idleFree tier; per-op billing can spike
Questions

Answered plainly.

Including the ones with awkward answers.

Is Lunora production-ready?

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.

Where does my data live?

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.

Can I self-host it?

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.

What is the data model?

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.

Which frontends are supported?

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.

What does it cost to run?

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.

Open source

Built in the open, on purpose.

Nothing about Lunora is a black box. Read it, fork it, or send the fix yourself.

Get started

Ready to ship realtime apps?

Open source, deployed to your own Cloudflare account, with no infrastructure to manage.

Start building