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. When anyone sends a
message, every open client updates; there is no cache to invalidate and 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 pleasant to build on, but your data lives on someone else's servers. Raw Cloudflare gives you ownership and edge prices, but you hand-wire RPC, types, and subscriptions yourself.
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, with no rewrite and the 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 and 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.
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.
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.