Skip to content
DocspackagesDocumentation

@lunora/vite

The recommended dev-time experience — codegen, HMR, overlay.

PackagesVite

@lunora/vite is a Vite plugin factory. A single lunora() call wires up codegen, wrangler validation, the error overlay, and the Cloudflare Vite plugin so vite dev runs your Worker locally with full HMR.

// vite.config.ts
import { lunora } from "@lunora/vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default defineConfig({
    plugins: [react(), lunora()],
});

Options

OptionDefaultPurpose
schemaDir"lunora"Directory containing schema.ts + function files
generatedDir"lunora/_generated"Where to emit api.ts, server.ts, dataModel.ts
apiSpec"openapi"API spec emitted into _generated/: "openapi"/"openrpc"/"both"/"none"
studiotrueServe the Lunora studio at /__lunora during dev, or false to skip
cloudflaretruePass options to @cloudflare/vite-plugin, or false to skip
overlaytrueInject @visulima/vite-overlay for runtime errors; false to skip, or an options object to forward
validateWranglertrueCross-check wrangler.jsonc bindings against the schema
projectRootprocess.cwd()Override for monorepo setups

Codegen lifecycle

The plugin watches <schemaDir>/**/*.ts. On any change it parses the schema with ts-morph, regenerates _generated/*.ts, and the Vite module graph picks up the new types, so your editor sees the change before you can swap windows.

Wrangler validator

Compares the table tier modifiers in your schema with durable_objects.bindings, d1_databases, and r2_buckets in wrangler.jsonc. Reports missing bindings as Vite errors before they explode at deploy.

Studio

During dev the plugin mounts the Lunora studio at /__lunora so you can browse your schema, data, logs, and advisors without leaving the dev server. Set studio: false to turn it off.

Error overlay

The plugin injects @visulima/vite-overlay so runtime and codegen failures show up in the browser instead of only the terminal. On top of it Lunora registers solution finders that recognise framework-specific failures and render a fix hint in the overlay:

  • a missing or non-object-literal defineSchema(...)
  • a reserved or duplicate table name
  • an invalid .jurisdiction(...) value
  • a non-literal unique index flag
  • a container/workflow class that isn't re-exported by your worker entry
  • runtime unique-constraint and optimistic-concurrency (ConflictError) conflicts

Pass an options object to forward overlay configuration, including your own solutionFinders, which run alongside Lunora's (each error resolves to the highest-priority finder that recognises it):

lunora({
    overlay: {
        solutionFinders: [myCustomFinder],
    },
});

Set overlay: false to disable it entirely.

Dev-server state & AI agents

While vite dev runs, the plugin registers the server in .lunora/dev.json (URL, PID, start time; per-checkout, gitignored, secret-free) and removes the record on shutdown. That record is what lets lunora dev status, lunora dev stop, and lunora dev logs manage a Vite-based project, and what lunora dev --background blocks on before reporting the URL and PID. An AI agent can then start, health-check (GET /_lunora/status on the worker), and stop your dev server without parsing terminal output or leaking zombie processes.

When an AI agent is detected (or LUNORA_LOG_JSON=1 is set), the worker's structured log events pass through as raw single-line JSON instead of the pretty [lunora] terminal rendering, so machine consumers can parse them directly. Set LUNORA_AGENT_MODE=0 to opt out of agent detection.