maravilla-overview
Maravilla Cloud Overview
Maravilla Cloud is a secure, edge-deployed JavaScript runtime that ships with a full backend platform built in. You write a normal SvelteKit / React Router 7 / Nuxt app, declare your auth and resource policies in maravilla.config.ts, and the runtime hands your code a platform object with KV, document DB, object storage, auth, realtime channels, Web Push, durable workflows, and event handlers.
There is no separate "deploy a function" step — your framework's server bundle is the runtime, and the platform services are imported as a typed SDK.
Runtime model
- Each request runs in a Deno V8 isolate (per-tenant). No shared state across tenants — Layer 1 isolation is unconditional.
- Cold starts target <100 ms; per-worker baseline is <50 MB.
- The runtime polyfills
URL,Request/Response, streaming,setTimeout, etc., so framework code runs unchanged. - Two production-grade backends ship: MongoDB-mode (
platform.env.DB) and aproduction-sqlitefeature flag for per-tenant SQLite (vector search lives here, see maravilla-db). - In dev mode, Vite runs on its usual port (5173) and a Rust dev-server on 3001 provides the platform APIs. The Vite plugin injects
platforminto SSR.
Single entry point: getPlatform()
import { getPlatform } from '@maravilla-labs/platform';
const platform = getPlatform();
// platform.env.KV.<namespace> — key/value
// platform.env.DB — document DB (Mongo-style + vector)
// platform.env.STORAGE — object storage / presigned URLs
// platform.auth — auth + identity binding + can()
// platform.policy — per-request Layer-2 toggle
// platform.realtime — pub/sub + presence
// platform.push — Web Push (server side)
// platform.workflows — durable, replay-based workflows
// platform.media — optional, when media is configured
getPlatform() returns the same shape in dev and prod. In dev the calls are proxied to the Rust dev-server; in prod they short-circuit through the host runtime.
What goes where
The most common confusion when starting out is which surface to use for which kind of state. Quick map:
| Need | Use | Notes |
|---|---|---|
| Small JSON blobs, sessions, feature flags | KV | Namespaced. TTL via expirationTtl. Prefix listing. |
| Structured data, queries, indexes | DB | Mongo-style filters + $set/$inc/$push. createIndex, findSimilar for vectors. |
| Files, images, video | STORAGE | Presigned upload URLs. getAssetUrl() for <img src>. |
| Pub/sub between tabs / users | realtime | publish, channels, presence. |
| Browser notifications | push | VAPID, idempotent key, recurring everySeconds. |
| Long-running, multi-step, durable | workflows | Replay model — step.run, step.sleep, step.waitForEvent. |
| React to data changes | events | events/*.ts files: onKvChange, onDb, onAuth, onSchedule, onStorage, onChannel, onQueue, onDeploy. |
The auth contract is critical
If you wire anything user-facing, read maravilla-auth before writing code. Every request that touches KV/DB/Storage as an authenticated user must do three things, in order:
platform.auth.validate(token)— confirm the JWTplatform.auth.setCurrentUser(token)— bind identity for this request- Operate normally; Layer-2 policies will see
auth.user_idon every op
Skipping step 2 silently makes the request anonymous. Owner-scoped policies (auth.user_id == node.owner) then return zero rows and the UI looks "broken" with no error.
Project layout
my-app/
├── maravilla.config.ts # Declarative auth, resources, indexes, transforms
├── events/ # Auto-discovered event handlers
│ ├── onUserRegistered.ts
│ └── tagNewTodoItem.ts
├── workflows/ # Durable workflows (defineWorkflow)
│ └── inviteeClickWatch.ts
├── src/ # Your framework code (SvelteKit / RR7 / Nuxt)
│ ├── hooks.server.ts # Bind auth from cookie (3-step contract)
│ └── routes/...
└── package.json
The framework adapter (@maravilla-labs/adapter-sveltekit, @maravilla-labs/adapter-react-router, @maravilla-labs/preset-nitro) discovers events/*.ts and workflows/*.ts at build time and bundles them into the deployed manifest.
Two layers of authorization
- Layer 1 — tenant + owner isolation. Always on. A request can never see another tenant's data, full stop. Not configurable.
- Layer 2 — per-resource policies. Declarative expressions in
maravilla.config.tslikeauth.user_id == node.owner || auth.is_admin. Evaluated on every KV/DB/realtime/media op against that resource. Can be temporarily disabled per-request viaplatform.policy.setEnabled(false)for trusted in-app flows (admin jobs, seeders) — every flip is audit-logged.
Frameworks supported
- SvelteKit via
@maravilla-labs/adapter-sveltekit— see sveltekit - React Router 7 via
@maravilla-labs/adapter-react-router— see react-router - Nuxt / Nitro via
@maravilla-labs/preset-nitro— see nuxt
Next.js is not supported.
Hello, world
// src/routes/+page.server.ts (SvelteKit)
import { getPlatform } from '@maravilla-labs/platform';
export async function load() {
const platform = getPlatform();
const todos = await platform.env.KV.todos.list({ prefix: 'item:' });
return { todos: todos.keys };
}
That's it. The runtime tags the request with the caller's tenant + identity (provided your hook ran the 3-step contract), the policy engine gates access, and your KV namespace is per-project per-tenant.
Where to go next
- Configure auth + policies → maravilla-config, maravilla-auth, maravilla-policies
- Pick your framework → sveltekit, react-router, nuxt
- Reach for storage → kv, db, storage
- React to changes → events, workflows
- Real-time + push → realtime, push
Full reference: https://www.maravilla.cloud/llms-full.txt.
More from maravilla-labs/maravilla-cli
maravilla-auth
Maravilla Cloud authentication. Use whenever wiring login/register/session, OAuth callbacks, resource policies, or hitting `platform.auth.*` APIs. Critical: the 3-step request-scoped contract (validate → setCurrentUser → can) — skipping any step silently breaks Layer-2 policies and owner-scoped reads return empty with no error.
12maravilla-events
Maravilla Cloud event handlers — files in `events/*.ts` auto-discovered by the framework adapter. Use to react to data changes (`onKvChange`, `onDb`), auth lifecycle (`onAuth`), schedule (`onSchedule`), queue messages (`onQueue`), realtime publishes (`onChannel`), deploy phases (`onDeploy`), object storage (`onStorage`), or arbitrary REN events (`defineEvent`). Run inside the Maravilla runtime with full platform access via `ctx`.
12maravilla-workflows
Maravilla Cloud durable workflows — replay-based, multi-step processes that survive restarts. Use whenever you need sleeps spanning minutes/hours/days, multi-step pipelines where each step's output feeds the next, waiting for external events, or strict step-history audit. `defineWorkflow` from `@maravilla-labs/functions/workflows/runtime` with `step.run`, `step.sleep`, `step.sleepUntil`, `step.waitForEvent`, `step.invoke`.
12maravilla-media-transforms
Async media + document derivations via `platform.media.transforms` and the declarative `transforms` block in `maravilla.config.ts`. Media: transcode video, thumbnail extraction, image resize/variants, OCR. Documents (.docx/.odt/.pptx/.xlsx/...): convert to PDF, render page thumbnails, generic format conversion, Markdown extraction (RAG-ready), single-file HTML with inlined images, image-replacement templating ({{TAG}} swap + named-object swap), QR-code injection. Use when ingesting user uploads that need normalised renditions, generating contracts/invoices from templates, or extracting structured content for LLMs. Critical: derived keys are content-addressed — `keyFor(srcKey, spec)` is known up front, before the worker starts, so clients can render placeholder UI without round-trips. Declarative config is the default; imperative `transforms.*` calls are for one-offs.
12maravilla-db
Maravilla Cloud document database — MongoDB-style queries, secondary indexes, and vector search. Use for structured app data, multi-field queries, sorting, semantic search via `findSimilar` / hybrid `find` with `options.vector`. Exposed as `platform.env.DB`. Vector indexes support int8/bit quantization, matryoshka, and multi-vector (ColBERT) out of the box.
11maravilla-config
The `maravilla.config.ts` declarative project file. Use whenever creating or modifying auth resources, groups, relations, registration fields, OAuth providers, password/session policy, branding, database indexes, or media transforms. Reconciled into delivery on every deploy — partial adoption is supported (omit a section to leave it untouched).
11