Skip to content
anolilabPublic

About

Type-safe, real-time backend framework on your own Cloudflare account — Workers, Durable Objects, D1, R2, Queues. Convex-style DX, Vite-first.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

286 stars

Watchers

0 watching

Forks

Latest commit

 

History

11,151 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lunora

Type-safe, real-time backend on your own Cloudflare account. Vite-first.

Documentation · Website · Packages · Quick start


typescript-image FSL-1.1-Apache-2.0 licence Status Node pnpm CI npm version PRs Welcome OpenSSF Scorecard


Daniel Bannert's open source work is supported by the community on GitHub Sponsors


What is Lunora?

Lunora gives you Convex-style DX on your own Cloudflare account. You write type-safe queries, mutations, and actions in TypeScript, and Lunora deploys them as Cloudflare Workers. Durable Objects hold real-time state, D1 handles SQL, R2 stores blobs, and Queues run jobs. Nothing runs on servers we operate; everything lives in the Cloudflare account you already pay for.

Lunora is Vite-first. The dev loop, codegen, and client bindings plug into a Vite project through @cloudflare/vite-plugin, so local dev runs on workerd, the same runtime as production. Rsbuild and Rspack projects get the same loop through @lunora/rspack, and a standalone CLI covers everything else.

Quick start

pnpm dlx lunorash@alpha init my-app
cd my-app
pnpm install
pnpm dev

Alpha. The npm package is lunorash because the unscoped lunora name is taken; the CLI it installs is still called lunora. Install from the @alpha dist-tag and expect breaking changes until the first stable release (see Status).

Prefer managed hosting, or just want one email when v1 is stable? Join the Lunora Cloud waitlist →

A fresh app has three files you edit:

// lunora/schema.ts
import { defineSchema, defineTable, v } from "lunorash/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 { mutate: send } = useMutation(api.messages.send);
    return (
        <>
            <button onClick={() => send({ author: "me", body: "hello" })}>Send</button>
            <ul>
                {messages.map((m) => (
                    <li key={m._id}>
                        {m.author}: {m.body}
                    </li>
                ))}
            </ul>
        </>
    );
}

pnpm dev boots workerd, generates the client types, starts the Vite dev server, and reloads on every save. Click the button and the list updates in every open tab; the query re-runs on the server and pushes the new result.

lunora init asks which framework to use and defaults to a React SPA. Pass -t to pick one directly: next, nuxt, sveltekit, astro, analog, react-router, tanstack-start-react, tanstack-start-solid, solid-v2, expo, vinext, rspack-react, standalone, and a few more (lunora init --help lists them). Use --vite <framework> for a plain React, Vue, Solid, or Svelte SPA, and lunora init --here to add Lunora to an app you already have.

Why Lunora

Types run end to end. The schema, validators, query results, and client hooks come from one source of truth. The dev server regenerates client types on save, so there is no codegen step to forget.

Queries are live. Clients subscribe over WebSocket, and a mutation pushes the change to every subscriber. You don't write cache invalidation.

It runs on your account. Workers, Durable Objects, D1, R2, Queues, and KV all live in your Cloudflare account. The only lock-in is Cloudflare itself.

It grows past one Durable Object. Every app starts on a single Durable Object. When one tenant needs its own, add .shardBy(key) to the function; for geo-replicated reads, add .global(). The rest of the app stays the same.

Features come as add-ons. Auth, mail, storage, scheduling, queues and pub/sub topics, workflows, AI agents, payments, feature flags, rate limiting, and notifications ship as @lunora/* packages or as items you copy in with lunora registry add. Other packages add typed access to Cloudflare Containers, Browser Rendering, Hyperdrive, AI Search, and service bindings to sibling Workers.

Clients aren't limited to JavaScript. There are adapters for React, Vue, Solid, Svelte, Angular, and React Native, and lunora sdk generate writes typed clients for Python, Go, Ruby, Rust, Swift, Java, Kotlin, and Dart (see sdks/).

The core doesn't depend on Cloudflare. The reactive engine (@lunora/shard-engine) talks to a small set of host contracts in @lunora/platform, not to Cloudflare APIs. @lunora/platform-cloudflare implements those contracts for production and @lunora/platform-node for dev and test. A capability matrix marks each feature as native, emulated, or unsupported per host; codegen leaves out what a host can't run and tells you why.

Lunora Studio

pnpm dev also serves Lunora Studio, a local admin UI for your app. In it you can browse and edit data, run SQL, watch live connections and function metrics, follow logs and traces, and see errors grouped into Issues. Time Travel replays past state, the architecture view draws a diagram from your code's call graph, and the advisors flag security and performance problems in your schema.

Lunora Studio, the local admin UI for your schema, data, functions, and advisors

Read the 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

Convex still has more built in than Lunora. What you get in exchange is ownership of the infrastructure and its cost: an idle Lunora app costs nothing, and at scale you pay Cloudflare's prices rather than a SaaS markup.

Architecture

                        ┌────────────────────────────────────┐
                        │  Browser / Node / RN client        │
                        │  @lunora/client · @lunora/react    │
                        └─────────────────┬──────────────────┘
                                          │  HTTPS + WebSocket (RPC envelope)
                                          ▼
                        ┌────────────────────────────────────┐
                        │  Vite / Rspack dev (workerd)        │
                        │  @lunora/vite · @lunora/rspack      │
                        │  or standalone: @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
                  │
                  └── @lunora/shard-engine (host-neutral: state, OCC,
                      CDC, reactivity) over @lunora/platform contracts,
                      implemented for this target by
                      @lunora/platform-cloudflare

Packages

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.json and project.json. Run pnpm run generate:packages-list to refresh it.

Runtime

Package Version Description
@lunora/d1 npm D1 adapter for Lunora .global() tables, wrapping the Sessions API for read-your-writes
@lunora/do npm Lunora Durable Objects: ShardDO (SQLite, OCC, hibernated WebSocket subscriptions) and SessionDO
@lunora/errors npm Unified error layer for Lunora: one LunoraError base + a central catalog of codes, statuses, and actionable hints, rendered across CLI, overlay, Studio, and the client
@lunora/fingerprint npm Zero-dependency, cross-runtime error fingerprinting for Lunora: a stable grouping hash that collapses noisy errors into Issues across the local Studio and the Cloud
@lunora/runtime npm Lunora Worker runtime: the RPC router, shard resolver, and query coordinator
@lunora/server npm Server primitives for Lunora: defineSchema, defineTable, query, mutation, and action
@lunora/sql-store npm Internal dialect-parameterized SQL store core for Lunora .global() backends (D1, PlanetScale)
@lunora/values npm Validators for Lunora: the v.* validator suite with end-to-end return-type inference
lunorash npm 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/angular npm Angular reactive adapter for Lunora — signal-based live queries and mutations
@lunora/astro npm Astro integration for Lunora — single-worker composition plus reactive-loader server helpers
@lunora/client npm Lunora browser SDK: WebSocket transport, optimistic updates, and an offline mutation queue
@lunora/db npm TanStack DB binding: typed, live-synced collections and a durable offline outbox over the Lunora client
@lunora/nuxt npm Nuxt module for Lunora — single-worker composition (mounts /_lunora/* into Nitro) plus reactive-loader server helpers
@lunora/react npm React hooks for Lunora: useQuery, useMutation, useSubscription, and useAuth
@lunora/react-native npm React Native / Expo integration for Lunora: an AsyncStorage-backed client factory, the useQuery/useMutation/useSubscription hooks, and a one-call better-auth Expo client
@lunora/solid npm SolidJS adapter for Lunora — live queries, optimistic mutations, and reactive loaders
@lunora/studio npm The Lunora Studio: a local admin UI for your schema, data, logs, and advisors
@lunora/svelte npm Svelte adapter for Lunora — live stores, optimistic mutations, and reactive loaders
@lunora/vue npm Vue adapter for Lunora — live composables, optimistic mutations, and reactive loaders

CLI

Package Version Description
@lunora/cli npm The Lunora CLI: init, dev, deploy, codegen, migrate, seed, doctor, insights, logs, registry, and the rest of the project commands

Codegen

Package Version Description
@lunora/codegen npm Code generator for Lunora: emits _generated/{api,server,dataModel}.ts from your schema

Bundler Plugins

Package Version Description
@lunora/rspack npm The Lunora Rspack plugin: codegen, binding provisioning, and wrangler validation for Rspack projects
@lunora/vite npm The Lunora Vite plugin: codegen, type sync, wrangler validation, and an error overlay over @cloudflare/vite-plugin

Dev Tools

Package Version Description
@lunora/config npm Internal shared CLI + Vite config layer for Lunora: wrangler.jsonc validation, binding inference, and .dev.vars scaffolding
@lunora/testing npm Testing toolkit for Lunora: an in-memory harness for queries, mutations, and actions

Advisor

Package Version Description
@lunora/advisor npm Schema & query lints (splinter-style advisors) for Lunora, feeding the Studio Advisors view

Add-ons

Package Version Description
@lunora/agent npm Durable AI agents for Lunora: defineAgent compiles a replay-safe tool-loop onto Cloudflare Workflows, with DO SQLite threads and live message subscriptions
@lunora/ai npm Workers AI helper for Lunora: provider-agnostic AI SDK access from functions, Workers AI by default
@lunora/auth npm Auth for Lunora — a thin better-auth wrapper: email/password, OAuth, plugins, D1-backed
@lunora/bindings npm Lightweight Cloudflare binding helpers for Lunora — ctx.kv, ctx.images, ctx.analytics, ctx.pipelines, ctx.vectors, ctx.r2sql, ctx.artifacts, ctx.aiSearch, ctx.analyticsSql — one install, per-binding subpaths
@lunora/browser npm Cloudflare Browser Rendering for Lunora: ctx.browser screenshots, PDF, and scraping in actions
@lunora/cloudflare-access npm Cloudflare Access (Zero Trust) identity for Lunora — verify the Cf-Access-Jwt-Assertion JWT against your team JWKS and feed the verified identity into ctx.auth / RLS via a resolveIdentity adapter
@lunora/container npm Cloudflare Containers for Lunora: defineContainer, generated Container DO classes, and the ctx.containers action surface
@lunora/flags npm OpenFeature-based feature flags for Lunora — ctx.flags, useFlag, and a first-class Cloudflare Flagship provider with any OpenFeature provider pluggable
@lunora/hyperdrive npm Bring-your-own Postgres/MySQL for Lunora via Cloudflare Hyperdrive: a driver-agnostic, action-only ctx.sql
@lunora/mail npm Email for Lunora: Resend adapter, TSX templates, and queue-backed sends
@lunora/mcp npm Model Context Protocol server exposing a Lunora deployment to AI agents
@lunora/notify npm Multi-channel notifications for Lunora — ctx.notify / ctx.push over @visulima/notification: edge-safe Web Push + FCM, plus chat, in-app inbox and webhook channels, with subscription storage and queue-backed fan-out
@lunora/payment npm Provider-agnostic payments for Lunora: Stripe-first adapter, webhook sync, and subscription/payment state machine
@lunora/queue npm Cloudflare Queues for Lunora: defineQueue producers + consumers, the ctx.queues surface, and the generated queue() worker handler
@lunora/ratelimit npm Rate limiting: token-bucket / fixed-window / sliding-window algorithms, deny list, pluggable stores, and procedure middleware
@lunora/replica npm Local-first replica runtime + local SQLite mirror for Lunora
@lunora/scheduler npm Scheduling for Lunora: runAfter / runAt and Cron Triggers via SchedulerDO
@lunora/seed npm Schema-driven, deterministic database seeding for Lunora: realistic fake data from defineSchema
@lunora/storage npm R2-backed storage for Lunora: typed buckets and signed URLs
@lunora/workflow npm Durable workflows for Lunora: defineWorkflow over Cloudflare Workflows, generated WorkflowEntrypoint classes, and the ctx.workflows surface

Observability

Package Version Description
@lunora/observability npm Host-neutral telemetry storage and read models for Lunora, backing the Studio's Logs, Traces, Metrics and Issues views

Platform

Package Version Description
@lunora/platform npm Provider-neutral host contracts for Lunora: shard/socket/directory/scheduler interfaces, binding projections, and the platform capability matrix
@lunora/platform-celld npm celld implementation of the Lunora platform contracts: the Cloudflare host adapters recomposed for celld (self-hosted distributed Durable Objects) under an honest capability matrix
@lunora/platform-cloudflare npm Cloudflare implementation of the Lunora platform contracts: ShardHost, SocketHost, ShardDirectory, ShardKvStore over Durable Objects
@lunora/platform-node npm Node implementation of the Lunora platform contracts: ShardHost, SocketHost, ShardDirectory, ShardKvStore, SchedulerHost over better-sqlite3 and an in-process socket registry (dev/test target)
@lunora/shard-engine npm Host-neutral reactive engine for Lunora: per-shard state, OCC, CDC, reactive subscriptions, and the poke protocol. Consumes @lunora/platform host contracts and can be mounted on any platform host.

Web3

Package Version Description
@lunora/x402 npm Agentic payments (x402) for Lunora: charge agents per request (charge rail) and let your agents pay x402-gated resources (pay rail)

Examples

Runnable apps live in examples/: a todo app, team chat, a kanban board, realtime cursors, chess, a blog, a feedback board, TanStack Start, Expo, and focused demos for auth, payments, notifications, offline rejections, and service bindings.

Documentation

The full docs are at lunora.sh/docs: guides, concepts, framework adapters, and a reference for each package. Good places to start:

Status

Lunora is in alpha, and the APIs will break. Every package publishes continuously to the alpha dist-tag on npm (pnpm add lunorash@alpha). Each package has its own version, so the alpha numbers don't line up across packages. The latest tag only holds a 0.0.x placeholder; run npm view <pkg> dist-tags to see the real version. The API, the package boundaries, and the on-disk layout will all change before the first stable release.

New versions ship often enough to trip pnpm's minimumReleaseAge. If you use that setting, add "@lunora/*" and lunorash to minimumReleaseAgeExclude; otherwise pnpm can resolve a mix of packages that no longer match.

Read the code, file issues, and open PRs against the alpha branch. Just don't build a production system on it yet.

Contributing

Start with .github/CONTRIBUTING.md. The default branch is alpha, and PRs go there unless you are 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.

License

FSL-1.1-Apache-2.0 © 2026 anolilab and contributors. The source is available now, and each release becomes Apache-2.0 two years after it ships.

About

Type-safe, real-time backend framework on your own Cloudflare account — Workers, Durable Objects, D1, R2, Queues. Convex-style DX, Vite-first.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

286 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages