Type-safe, real-time backend on your own Cloudflare account. Vite-first.
Documentation · Website · Packages · Quick start
Daniel Bannert's open source work is supported by the community on GitHub Sponsors
Lunora is Convex DX on your own Cloudflare account. You write type-safe queries, mutations, and actions in TypeScript; Lunora turns them into Cloudflare Workers backed by Durable Objects for real-time state, D1 for SQL, R2 for blobs, and Queues for jobs. There are no proprietary servers in the loop — only the Cloudflare account you already pay for.
It is Vite-first: the dev loop, codegen, and client bindings plug into a Vite project via @cloudflare/vite-plugin, so dev runs on workerd (the same runtime as production). A standalone CLI fallback exists for non-Vite users.
pnpm dlx lunorash@alpha init my-app
cd my-app
pnpm devAlpha: the npm package is
lunorash(the unscopedlunoraname is taken on npm); the CLI binary it installs is stilllunora. Install from the@alphadist-tag and expect breaking changes until the first stable release.
Prefer managed hosting, or just want one email when v1 is stable? Join the Lunora Cloud waitlist →
Three visible files in a fresh app:
// lunora/schema.ts
import { defineSchema, defineTable, v } from "@lunora/server";
export default defineSchema({
messages: defineTable({
author: v.string(),
body: v.string(),
ts: v.number(),
}),
});// lunora/messages.ts
import { mutation, query, v } from "./_generated/server";
export const list = query.query(async ({ ctx }) => ctx.db.query("messages").order("desc").take(50));
export const send = mutation.input({ author: v.string(), body: v.string() }).mutation(async ({ ctx, args }) => {
await ctx.db.insert("messages", { ...args, ts: Date.now() });
});// src/App.tsx
import { useQuery, useMutation } from "@lunora/react";
import { api } from "../lunora/_generated/api";
export default function App() {
const messages = useQuery(api.messages.list) ?? [];
const send = useMutation(api.messages.send);
return (
<ul>
{messages.map((m) => (
<li key={m._id}>
{m.author}: {m.body}
</li>
))}
</ul>
);
}pnpm dev boots workerd, generates the client types, opens the Vite dev server, and live-reloads on every save.
- End-to-end type safety. Server schema, validators, query results, and React hooks all share one source of truth. No client codegen step you forget to re-run.
- Real-time by default. Queries are reactive over WebSocket subscriptions; mutations push deltas to subscribed clients without manual cache invalidation.
- Your data, your account. Everything runs on your Cloudflare resources (Workers, Durable Objects, D1, R2, Queues, KV). No vendor lock-in beyond Cloudflare itself.
- Scales past the single-DO ceiling. Start simple with one Durable Object; opt into
.shardBy(key)per function when you need tenant-level isolation, or.global()for geo-replicated reads, without rewriting your app.
Every app ships with Lunora Studio — a local admin UI for your schema, data, functions, logs, and advisors, served automatically by pnpm dev. Browse and edit data, run SQL, inspect live connections and function metrics, replay state with Time Travel, and read the security & performance advisories generated from your schema.
Read the Studio deep dive →
| 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 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 |
Lunora has fewer batteries-included features than Convex today. The trade you make is infrastructure ownership and cost — at idle, Lunora is free; at scale, you pay Cloudflare prices, not SaaS prices.
┌────────────────────────────────────┐
│ Browser / Node / RN client │
│ @lunora/client · @lunora/react │
└─────────────────┬──────────────────┘
│ HTTPS + WebSocket (RPC envelope)
▼
┌────────────────────────────────────┐
│ Vite dev (workerd) or Standalone │
│ @lunora/vite │ @lunora/cli │
└─────────────────┬──────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Cloudflare Worker — @lunora/runtime │
│ · parses RPC · auth · routing │
│ · upgrades WS to ShardDO via idFromName(key) │
└───┬──────────┬───────────┬───────────┬──────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌───────┐ ┌────────┐ ┌──────┐ ┌──────────┐
│ Shard │ │Session │ │ D1 │ │R2/Queues │
│ DO │ │ DO │ │ SQL │ │ KV │
│(state)│ │ (auth) │ │ │ │ │
└───────┘ └────────┘ └──────┘ └──────────┘
│
└── SQLite-backed, WebSocket Hibernation API,
subscription registry
All packages are published under the @lunora npm scope (except the unscoped umbrella lunorash) and live under packages/.
This table is generated from each package's
package.jsonandproject.json. Runpnpm run generate:packages-listto refresh it.
| Package | Version | Description |
|---|---|---|
@lunora/d1 |
D1 adapter for Lunora .global() tables, wrapping the Sessions API for read-your-writes | |
@lunora/do |
Lunora Durable Objects: ShardDO (SQLite, OCC, hibernated WebSocket subscriptions) and SessionDO | |
@lunora/runtime |
Lunora Worker runtime: the RPC router, shard resolver, and query coordinator | |
@lunora/server |
Server primitives for Lunora: defineSchema, defineTable, query, mutation, and action | |
@lunora/sql-store |
Internal dialect-parameterized SQL store core for Lunora .global() backends (D1, PlanetScale) | |
@lunora/values |
Validators for Lunora: the v.* validator suite with end-to-end return-type inference | |
lunorash |
The Lunora umbrella package: one install for the server authoring API, worker runtime, Durable Objects, and the lunora CLI |
| Package | Version | Description |
|---|---|---|
@lunora/astro |
Astro integration for Lunora — single-worker composition plus reactive-loader server helpers | |
@lunora/client |
Lunora browser SDK: WebSocket transport, optimistic updates, and an offline mutation queue | |
@lunora/db |
TanStack DB binding: typed, live-synced collections and a durable offline outbox over the Lunora client | |
@lunora/nuxt |
Nuxt module for Lunora — single-worker composition (mounts /_lunora/* into Nitro) plus reactive-loader server helpers | |
@lunora/react |
React hooks for Lunora: useQuery, useMutation, useSubscription, and useAuth | |
@lunora/solid |
SolidJS adapter for Lunora — live queries, optimistic mutations, and reactive loaders | |
@lunora/studio |
The Lunora Studio: a local admin UI for your schema, data, logs, and advisors | |
@lunora/svelte |
Svelte adapter for Lunora — live stores, optimistic mutations, and reactive loaders | |
@lunora/vue |
Vue adapter for Lunora — live composables, optimistic mutations, and reactive loaders |
| Package | Version | Description |
|---|---|---|
@lunora/cli |
The Lunora CLI: init, dev, deploy, codegen, run, reset, and migrate commands |
| Package | Version | Description |
|---|---|---|
@lunora/codegen |
Code generator for Lunora: emits _generated/{api,server,dataModel}.ts from your schema |
| Package | Version | Description |
|---|---|---|
@lunora/vite |
The Lunora Vite plugin: codegen, type sync, wrangler validation, and an error overlay over @cloudflare/vite-plugin |
| Package | Version | Description |
|---|---|---|
@lunora/config |
Internal shared CLI + Vite config layer for Lunora: wrangler.jsonc validation, binding inference, and .dev.vars scaffolding | |
@lunora/testing |
Testing toolkit for Lunora: an in-memory harness for queries, mutations, and actions |
| Package | Version | Description |
|---|---|---|
@lunora/advisor |
Schema & query lints (splinter-style advisors) for Lunora, feeding the Studio Advisors view |
| Package | Version | Description |
|---|---|---|
@lunora/ai |
Workers AI helper for Lunora: provider-agnostic AI SDK access from functions, Workers AI by default | |
@lunora/auth |
Auth for Lunora — a thin better-auth wrapper: email/password, OAuth, plugins, D1-backed | |
@lunora/bindings |
Lightweight Cloudflare binding helpers for Lunora — ctx.kv, ctx.images, ctx.analytics (+ Pipelines), ctx.vectors, ctx.r2sql — one install, per-binding subpaths | |
@lunora/browser |
Cloudflare Browser Rendering for Lunora: ctx.browser screenshots, PDF, and scraping in actions | |
@lunora/container |
Cloudflare Containers for Lunora: defineContainer, generated Container DO classes, and the ctx.containers action surface | |
@lunora/dispatch |
Shared dispatch runner for Lunora: call a Lunora function from a server-initiated context (workflow/queue/scheduled job) via /_lunora/scheduler/dispatch | |
@lunora/flags |
OpenFeature-based feature flags for Lunora — ctx.flags, useFlag, and a first-class Cloudflare Flagship provider with any OpenFeature provider pluggable | |
@lunora/hyperdrive |
Bring-your-own Postgres/MySQL for Lunora via Cloudflare Hyperdrive: a driver-agnostic, action-only ctx.sql | |
@lunora/mail |
Email for Lunora: Resend adapter, TSX templates, and queue-backed sends | |
@lunora/mcp |
Model Context Protocol server exposing a Lunora deployment to AI agents | |
@lunora/payment |
Provider-agnostic payments for Lunora: Stripe-first adapter, webhook sync, and subscription/payment state machine | |
@lunora/queue |
Cloudflare Queues for Lunora: defineQueue producers + consumers, the ctx.queues surface, and the generated queue() worker handler | |
@lunora/ratelimit |
Rate limiting: token-bucket / fixed-window / sliding-window algorithms, deny list, sharding, pluggable stores, and procedure middleware | |
@lunora/scheduler |
Scheduling for Lunora: runAfter / runAt and Cron Triggers via SchedulerDO | |
@lunora/seed |
Schema-driven, deterministic database seeding for Lunora: realistic fake data from defineSchema | |
@lunora/storage |
R2-backed storage for Lunora: typed buckets and signed URLs | |
@lunora/workflow |
Durable workflows for Lunora: defineWorkflow over Cloudflare Workflows, generated WorkflowEntrypoint classes, and the ctx.workflows surface |
Full documentation lives at lunora.sh/docs — guides, core concepts, framework adapters, and per-package reference:
- Getting started — scaffold an app and run the dev loop in under a minute
- Queries, mutations & actions — the core authoring model
- Real-time · Sharding · RLS — the concepts that make it scale
- Architecture — how the Worker, Durable Objects, and storage fit together
- Deployment — ship to your own Cloudflare account
- Packages — every
@lunora/*adapter and add-on
v1.0.0-alpha.1 — APIs WILL break. This is bootstrap-quality. Nothing is on npm yet; the surface area, package boundaries, and on-disk layout will all shift before the first non-alpha tag.
You are welcome to read, file issues, and open PRs against the alpha branch. Just don't build a production system on it yet.
See .github/CONTRIBUTING.md. The default branch is alpha; PRs target alpha unless explicitly cutting a release.
For security reports, see SECURITY.md. For community guidelines, see .github/CODE_OF_CONDUCT.md. For brand assets and usage rules, see marketing/BRAND.md.
FSL-1.1-Apache-2.0 © 2026 anolilab and contributors. Source-available; each release converts to Apache-2.0 two years after it ships.