alpha · v0.1.0 built on Bun · deployed on Railway Edge

Ship the thing.
Skip the plumbing.

Luminaweb is an agent-native runtime for full-stack TypeScript apps called capsules. One directory, one port, one command. No docker. No yaml. No 3am deploys.

$ npm i -g luminaweb $ luminaweb new my-app --template todo $ cd my-app && luminaweb dev ▌ ready on http://localhost:3000 · 14ms cold start

An agent-native
runtime.

You write a capsule() with a schema, queries, mutations, and a Preact UI. Luminaweb handles the rest: server authority, routing, persistence, deploys, the boring parts.

The runtime is small enough to read in a sitting. It stays out of your way. No framework churn, no opinion on your folder structure.

Three files.
That's the whole app.

The capsule lives in one directory. A server contract, a Preact client, a shared/ folder for types, and an optional .env.luminaweb.server for secrets. No build config. No router config. No bundler config.

my-app/ ├── server/ │ └── index.ts // capsule, schema, queries, mutations ├── client/ │ └── index.tsx // Preact UI ├── shared/ │ └── todo.ts // pure types & helpers ├── .env.luminaweb.server // server-only secrets └── package.json
server/index.ts TypeScript
import { boolean, capsule, mutation, query, string, table } from "@luminaweb/runtime/server"; export default capsule({ schema: { todos: table({ text: string(), done: boolean(), ownerId: string(), }), }, queries: { todos: query((ctx) => ctx.db.todos.where("ownerId", ctx.auth.userId).all(), ), }, mutations: { addTodo: mutation((ctx, text: string) => { ctx.db.todos.insert({ text, done: false, ownerId: ctx.auth.userId }); }), }, });

why it works

Built for the agent,
not the framework.

01

Server-authoritative

Queries and mutations are the source of truth. The client never writes to tables. Re-check ownership in every mutation. The runtime preserves ordinary control flow in the server sandbox, so the contract stays the contract.

02

Persistent by default

Local dev writes to a real SQLite file. Edge deploys get a managed SQLite. No in-memory resets. The data outlives the process.

03

One port, one bundle

The client, the server, and the static SPA all live on the same origin. One deploy artifact, one process, one URL. No CORS archaeology.

04

Typed through and through

useQuery<Todo[]>("todos") is end-to-end typed. Rename a query and the client errors in the editor, not in production.

05

Runs on Railway Edge

luminaweb deploy pushes your capsule to the Luminaweb Edge. Anonymous deploys go through in seconds. Claim for stable subdomains.

06

Inspectable

luminaweb db dump, luminaweb logs, luminaweb inspect. The CLI reads .luminaweb/deploy.json and sends the claim token automatically. No portal, no click-ops.

deploy

From my-app/
to live in one command.

  1. 01 luminaweb build --target edge bundle server.mjs + client/bundle.js
  2. 02 luminaweb deploy push to edge.luminaweb.app
  3. 03 luminaweb claim opt in for env, fetch, and subdomains
live url https://my-app.luminaweb.app

Build the thing.
The runtime will keep up.

Read the quickstart