Overview
The Convex-style real-time backend that runs on your own Cloudflare account — typed end to end, live by default, ~$0 at idle.
Last updated:
Lunora is a type-safe, real-time backend that runs entirely on your own Cloudflare Workers + Durable Objects account. You write a schema and some TypeScript functions. Lunora turns them into edge Workers with end-to-end types and reactive hooks that update live over WebSockets.
It's the developer experience of a managed platform like Convex — without handing over your data or watching the bill climb with your traffic. You own your data, you pay Cloudflare's edge prices, and it's open source.
// lunora/messages.ts
import { mutation, query, v } from "@/lunora/_generated/server";
export const send = mutation.input({ channelId: v.id("channels"), text: v.string() }).mutation(async ({ ctx, args }) => {
await ctx.db.insert("messages", { ...args, userId: ctx.auth.userId });
});
export const list = query.input({ channelId: v.id("channels") }).query(async ({ ctx, args }) =>
ctx.db
.query("messages")
.withIndex("by_channel", (q) => q.eq("channelId", args.channelId))
.collect(),
);That list query streams to the browser over WebSocket. Anyone sends a message,
every open client updates — no cache to invalidate, no endpoint to wire up.
Lunora is in alpha. Install from the @alpha dist-tag and expect breaking changes until the first stable release. You can build something real with it
today, but don't ship it to production yet.
Why Lunora
Every real-time app eventually hits the same fork in the road.
Managed platforms like Convex and Firebase are a joy to build on, but your data lives on someone else's servers. Raw Cloudflare gives you ownership and edge prices, but you spend your weekends hand-wiring RPC, types, and subscriptions — good bones, no developer experience.
Lunora is the third option: managed-platform DX, on the Cloudflare account you already pay for.
Type-safe, end to end
Schema, validators, query results, and hooks share one source of truth. Rename a field and the build breaks — in your editor, not in production.
Real-time by default
Every query is a live subscription over WebSocket, with optimistic writes and an offline queue. No cache to invalidate.
Runs on your account
Workers + Durable Objects on your own Cloudflare account. Your data, your hostname, roughly $0 at idle on the free tier.
Scales when you need it
Start with one Durable Object. Opt into sharding per function when you outgrow it — no rewrite, same call sites.
Secure by default
Opt-in, server-side row-level security and data masking. Authorization lives next to your data, not scattered across handlers.
Batteries, not lock-in
First-party auth, mail, storage, scheduler, workflows, payments, and AI — each a separate install, never a hard dependency.
Own it, or let us run it
The same code runs two ways, and you're never stuck with one:
- Self-host on your own Cloudflare account. Free, open source, your data, roughly $0 at idle on the free tier.
- Lunora Cloud (soon) — the same code, managed for you, for teams that would rather ship than babysit infrastructure.
You can always grab the open source and self-host. That's the whole point.
How Lunora compares
| Lunora | Convex | Firebase | Plain Cloudflare | |
|---|---|---|---|---|
| Type-safe end-to-end | Yes | Yes | Partial | DIY |
| Real-time subscriptions | Yes (WS, reactive) | Yes | Yes | DIY |
| Runs on your account | Yes (Cloudflare) | No (managed SaaS) | No (managed SaaS) | Yes |
| Scales past a single DO | Yes (.shardBy()) | n/a | n/a | DIY (manual) |
| Vite-first DX | Yes | n/a | n/a | DIY |
| Feature breadth (auth, mail, storage, scheduler) | Add-ons (alpha) | Broad (built-in) | Broad (built-in) | DIY |
| Cost at idle | ≈ $0 (CF free tier) | Paid | ≈ $0 (Spark tier) | ≈ $0 |
Want the full breakdown against Convex, Supabase, Firebase, and Appwrite? See the detailed comparison.
Where it's rough
Lunora has fewer built-in features than Convex right now, and it's alpha, so expect breaking changes before the first stable tag. If you need production-ready today, pick something mature. We'd rather say it here than have you find out the hard way.
What ships in v1.0.0-alpha.1
@lunora/server—defineSchema,defineTable,query,mutation,action, validators@lunora/runtime— Worker entrypoint, RPC envelope, shard routing@lunora/do—ShardDOandSessionDObase classes@lunora/d1— D1 Sessions API wrapper for.global()tables@lunora/client+@lunora/react/@lunora/vue/@lunora/solid/@lunora/svelte— browser SDK and framework adapters@lunora/vite+@lunora/cli— codegen, dev server, scaffolding@lunora/auth/@lunora/mail/@lunora/storage/@lunora/scheduler— first-party add-ons@lunora/bindings/vectors— Cloudflare Vectorize adapter for typed similarity search and RAG@lunora/workflow— durable, replayable multi-step workflows on Cloudflare Workflows@lunora/ratelimit/@lunora/payment— rate-limiting middleware and provider-agnostic payments@lunora/flags— OpenFeature feature flags (ctx.flags,useFlag), Cloudflare Flagship as the default provider- Row-level security + data masking — opt-in, server-side authorization in
@lunora/server @lunora/advisor— schema, performance, and security lints, surfaced in the studio@lunora/testing/@lunora/mcp— an in-memory test harness and an MCP server for AI agents@lunora/studio— a local admin console for data, functions, logs, and advisors
Start building
One command gives you a typed, live-syncing app on your own account:
pnpm dlx lunorash@alpha init my-apppnpm dev boots workerd — the real production runtime — generates your types,
and starts Vite with a local Studio. No Cloudflare account required: develop
locally, then lunora deploy --temporary pushes a live URL on a short-lived
account you can claim later. Sign up only when you're ready to keep it.