https://github.com/anolilab/lunora
Type-safe, real-time backend framework on your own Cloudflare account — Workers, Durable Objects, D1, R2, Queues. Convex-style DX, Vite-first.
https://github.com/anolilab/lunora
baas backend cloudflare cloudflare-workers convex d1 durable-objects edge framework full-stack r2 realtime serverless sqlite type-safe typescript vite websockets
Last synced: about 3 hours ago
JSON representation
Type-safe, real-time backend framework on your own Cloudflare account — Workers, Durable Objects, D1, R2, Queues. Convex-style DX, Vite-first.
- Host: GitHub
- URL: https://github.com/anolilab/lunora
- Owner: anolilab
- License: other
- Created: 2026-05-29T14:06:02.000Z (about 1 month ago)
- Default Branch: alpha
- Last Pushed: 2026-06-27T22:25:12.000Z (3 days ago)
- Last Synced: 2026-06-28T00:02:36.858Z (2 days ago)
- Topics: baas, backend, cloudflare, cloudflare-workers, convex, d1, durable-objects, edge, framework, full-stack, r2, realtime, serverless, sqlite, type-safe, typescript, vite, websockets
- Language: TypeScript
- Homepage: https://lunora.sh
- Size: 18.2 MB
- Stars: 37
- Watchers: 0
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: .github/CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
- Code of conduct: .github/CODE_OF_CONDUCT.md
- Codeowners: .github/CODEOWNERS
- Security: SECURITY.md
- Agents: AGENTS.md
Awesome Lists containing this project
README

**Type-safe, real-time backend on your own Cloudflare account. Vite-first.**
[**Documentation**](https://lunora.sh/docs) · [**Website**](https://lunora.sh) · [**Packages**](https://lunora.sh/packages) · [**Quick start**](#quick-start)
[![typescript-image][typescript-badge]][typescript-url]
[![FSL-1.1-Apache-2.0 licence][license-badge]][license]
[![Status][status-badge]][status]
[![Node][node-badge]][node]
[![pnpm][pnpm-badge]][pnpm]
[![CI][ci-badge]][ci]
[![npm version][npm-version-badge]][npm-version]
[![PRs Welcome][prs-welcome-badge]][prs-welcome]
---
---
## What is Lunora?
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.
## Quick start
```bash
pnpm dlx lunorash@alpha init my-app
cd my-app
pnpm dev
```
> **Alpha:** the npm package is **`lunorash`** (the unscoped `lunora` name is taken on npm); the CLI binary it installs is still **`lunora`**. Install from the `@alpha` dist-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 →](https://lunora.sh/cloud)**
Three visible files in a fresh app:
```ts
// lunora/schema.ts
import { defineSchema, defineTable, v } from "@lunora/server";
export default defineSchema({
messages: defineTable({
author: v.string(),
body: v.string(),
ts: v.number(),
}),
});
```
```ts
// 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() });
});
```
```tsx
// 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 (
-
{m.author}: {m.body}
{messages.map((m) => (
))}
);
}
```
`pnpm dev` boots workerd, generates the client types, opens the Vite dev server, and live-reloads on every save.
## Why Lunora
- **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.
## Lunora Studio
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 →](https://lunora.sh/blog/lunora-studio-deep-dive)
## Lunora vs. the alternatives
| | **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.
## Architecture
```
┌────────────────────────────────────┐
│ 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
```
## Packages
All packages are published under the [`@lunora`](https://www.npmjs.com/org/lunora) npm scope (except the unscoped umbrella `lunorash`) and live under `packages/`.
> This table is generated from each package's `package.json` and `project.json`. Run `pnpm run generate:packages-list` to refresh it.
### Runtime
| Package | Version | Description |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| [`@lunora/d1`](packages/d1/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fd1) | D1 adapter for Lunora .global() tables, wrapping the Sessions API for read-your-writes |
| [`@lunora/do`](packages/do/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fdo) | Lunora Durable Objects: ShardDO (SQLite, OCC, hibernated WebSocket subscriptions) and SessionDO |
| [`@lunora/runtime`](packages/runtime/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fruntime) | Lunora Worker runtime: the RPC router, shard resolver, and query coordinator |
| [`@lunora/server`](packages/server/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fserver) | Server primitives for Lunora: defineSchema, defineTable, query, mutation, and action |
| [`@lunora/sql-store`](packages/sql-store/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fsql-store) | Internal dialect-parameterized SQL store core for Lunora .global() backends (D1, PlanetScale) |
| [`@lunora/values`](packages/values/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fvalues) | Validators for Lunora: the v.\* validator suite with end-to-end return-type inference |
| [`lunorash`](packages/lunora/README.md) | [](https://www.npmjs.com/package/lunorash) | The Lunora umbrella package: one install for the server authoring API, worker runtime, Durable Objects, and the lunora CLI |
### Client & Framework Adapters
| Package | Version | Description |
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| [`@lunora/astro`](packages/astro/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fastro) | Astro integration for Lunora — single-worker composition plus reactive-loader server helpers |
| [`@lunora/client`](packages/client/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fclient) | Lunora browser SDK: WebSocket transport, optimistic updates, and an offline mutation queue |
| [`@lunora/db`](packages/db/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fdb) | TanStack DB binding: typed, live-synced collections and a durable offline outbox over the Lunora client |
| [`@lunora/nuxt`](packages/nuxt/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fnuxt) | Nuxt module for Lunora — single-worker composition (mounts /\_lunora/\* into Nitro) plus reactive-loader server helpers |
| [`@lunora/react`](packages/react/README.md) | [](https://www.npmjs.com/package/%40lunora%2Freact) | React hooks for Lunora: useQuery, useMutation, useSubscription, and useAuth |
| [`@lunora/solid`](packages/solid/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fsolid) | SolidJS adapter for Lunora — live queries, optimistic mutations, and reactive loaders |
| [`@lunora/studio`](packages/studio/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fstudio) | The Lunora Studio: a local admin UI for your schema, data, logs, and advisors |
| [`@lunora/svelte`](packages/svelte/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fsvelte) | Svelte adapter for Lunora — live stores, optimistic mutations, and reactive loaders |
| [`@lunora/vue`](packages/vue/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fvue) | Vue adapter for Lunora — live composables, optimistic mutations, and reactive loaders |
### CLI
| Package | Version | Description |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| [`@lunora/cli`](packages/cli/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fcli) | The Lunora CLI: init, dev, deploy, codegen, run, reset, and migrate commands |
### Codegen
| Package | Version | Description |
| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| [`@lunora/codegen`](packages/codegen/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fcodegen) | Code generator for Lunora: emits \_generated/{api,server,dataModel}.ts from your schema |
### Vite Plugin
| Package | Version | Description |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| [`@lunora/vite`](packages/vite/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fvite) | The Lunora Vite plugin: codegen, type sync, wrangler validation, and an error overlay over @cloudflare/vite-plugin |
### Dev Tools
| Package | Version | Description |
| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [`@lunora/config`](packages/config/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fconfig) | Internal shared CLI + Vite config layer for Lunora: wrangler.jsonc validation, binding inference, and .dev.vars scaffolding |
| [`@lunora/testing`](packages/testing/README.md) | [](https://www.npmjs.com/package/%40lunora%2Ftesting) | Testing toolkit for Lunora: an in-memory harness for queries, mutations, and actions |
### Advisor
| Package | Version | Description |
| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| [`@lunora/advisor`](packages/advisor/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fadvisor) | Schema & query lints (splinter-style advisors) for Lunora, feeding the Studio Advisors view |
### Add-ons
| Package | Version | Description |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`@lunora/ai`](packages/ai/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fai) | Workers AI helper for Lunora: provider-agnostic AI SDK access from functions, Workers AI by default |
| [`@lunora/auth`](packages/auth/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fauth) | Auth for Lunora — a thin better-auth wrapper: email/password, OAuth, plugins, D1-backed |
| [`@lunora/bindings`](packages/bindings/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fbindings) | Lightweight Cloudflare binding helpers for Lunora — ctx.kv, ctx.images, ctx.analytics (+ Pipelines), ctx.vectors, ctx.r2sql — one install, per-binding subpaths |
| [`@lunora/browser`](packages/browser/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fbrowser) | Cloudflare Browser Rendering for Lunora: ctx.browser screenshots, PDF, and scraping in actions |
| [`@lunora/container`](packages/container/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fcontainer) | Cloudflare Containers for Lunora: defineContainer, generated Container DO classes, and the ctx.containers action surface |
| [`@lunora/dispatch`](packages/dispatch/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fdispatch) | Shared dispatch runner for Lunora: call a Lunora function from a server-initiated context (workflow/queue/scheduled job) via /\_lunora/scheduler/dispatch |
| [`@lunora/hyperdrive`](packages/hyperdrive/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fhyperdrive) | Bring-your-own Postgres/MySQL for Lunora via Cloudflare Hyperdrive: a driver-agnostic, action-only ctx.sql |
| [`@lunora/mail`](packages/mail/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fmail) | Email for Lunora: Resend adapter, TSX templates, and queue-backed sends |
| [`@lunora/mcp`](packages/mcp/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fmcp) | Model Context Protocol server exposing a Lunora deployment to AI agents |
| [`@lunora/payment`](packages/payment/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fpayment) | Provider-agnostic payments for Lunora: Stripe-first adapter, webhook sync, and subscription/payment state machine |
| [`@lunora/queue`](packages/queue/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fqueue) | Cloudflare Queues for Lunora: defineQueue producers + consumers, the ctx.queues surface, and the generated queue() worker handler |
| [`@lunora/ratelimit`](packages/ratelimit/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fratelimit) | Rate limiting: token-bucket / fixed-window / sliding-window algorithms, deny list, sharding, pluggable stores, and procedure middleware |
| [`@lunora/scheduler`](packages/scheduler/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fscheduler) | Scheduling for Lunora: runAfter / runAt and Cron Triggers via SchedulerDO |
| [`@lunora/seed`](packages/seed/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fseed) | Schema-driven, deterministic database seeding for Lunora: realistic fake data from defineSchema |
| [`@lunora/storage`](packages/storage/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fstorage) | R2-backed storage for Lunora: typed buckets and signed URLs |
| [`@lunora/workflow`](packages/workflow/README.md) | [](https://www.npmjs.com/package/%40lunora%2Fworkflow) | Durable workflows for Lunora: defineWorkflow over Cloudflare Workflows, generated WorkflowEntrypoint classes, and the ctx.workflows surface |
## Documentation
Full documentation lives at **[lunora.sh/docs](https://lunora.sh/docs)** — guides, core concepts, framework adapters, and per-package reference:
- [Getting started](https://lunora.sh/docs/getting-started) — scaffold an app and run the dev loop in under a minute
- [Queries, mutations & actions](https://lunora.sh/docs/concepts/queries-mutations) — the core authoring model
- [Real-time](https://lunora.sh/docs/concepts/realtime) · [Sharding](https://lunora.sh/docs/concepts/sharding) · [RLS](https://lunora.sh/docs/concepts/rls) — the concepts that make it scale
- [Architecture](https://lunora.sh/docs/architecture) — how the Worker, Durable Objects, and storage fit together
- [Deployment](https://lunora.sh/docs/deployment) — ship to your own Cloudflare account
- [Packages](https://lunora.sh/packages) — every `@lunora/*` adapter and add-on
## Status
**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`](https://github.com/anolilab/lunora/tree/alpha) branch. Just don't build a production system on it yet.
## Contributing
See [`.github/CONTRIBUTING.md`](./.github/CONTRIBUTING.md). The default branch is **`alpha`**; PRs target `alpha` unless explicitly cutting a release.
For security reports, see [`SECURITY.md`](./SECURITY.md). For community guidelines, see [`.github/CODE_OF_CONDUCT.md`](./.github/CODE_OF_CONDUCT.md). For brand assets and usage rules, see [`marketing/BRAND.md`](./marketing/BRAND.md).
## License
[FSL-1.1-Apache-2.0](./LICENSE.md) © 2026 anolilab and contributors. Source-available; each release converts to Apache-2.0 two years after it ships.
[typescript-badge]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
[typescript-url]: https://www.typescriptlang.org/
[license-badge]: https://img.shields.io/badge/license-FSL--1.1--Apache--2.0-blue.svg?style=for-the-badge
[license]: ./LICENSE.md
[status-badge]: https://img.shields.io/badge/status-alpha-blueviolet.svg?style=for-the-badge
[status]: #status
[node-badge]: https://img.shields.io/badge/node-%5E22.15%20%7C%7C%20%3E%3D24.11-brightgreen.svg?style=for-the-badge
[node]: ./package.json
[pnpm-badge]: https://img.shields.io/badge/pnpm-11.5.3-f69220.svg?style=for-the-badge
[pnpm]: ./package.json
[ci-badge]: https://img.shields.io/github/actions/workflow/status/anolilab/lunora/test.yml?branch=alpha&style=for-the-badge&label=CI
[ci]: https://github.com/anolilab/lunora/actions/workflows/test.yml
[npm-version-badge]: https://img.shields.io/npm/v/lunorash/alpha?label=lunorash%40alpha&color=cb3837&style=for-the-badge
[npm-version]: https://www.npmjs.com/package/lunorash
[prs-welcome-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge
[prs-welcome]: https://github.com/anolilab/lunora/blob/alpha/.github/CONTRIBUTING.md