Skip to main content

Server Functions

Server functions are optional server-side logic that runs on the Lumio API. They let extensions persist structured data, query databases, call external APIs, and manage secrets — all in a sandboxed, isolated environment.

Enabling server functions

Add "server": true to lumio.config.json:

{
"server": true
}

This enables the server/ directory and activates the server runtime for your extension.

Two styles

StyleUse caseOverhead
DeclarativeSimple CRUD on tables (queryRows, insertRow, patchRow, deleteRow)Minimal — transpiles to parameterized SQL, no JS runtime
Handler-basedComplex logic, external APIs, conditional writes (query(), mutation(), action())Low — runs in a V8 isolate with memory and CPU limits

Execution flow

Extension Client (browser)
-> useMutation("addRule") / useQuery("getRules")
-> postMessage to Lumio host
-> Lumio API: POST /v1/extension-functions/{install_id}/{functionName}
-> Auth check + rate limit check
-> Declarative: parameterized SQL -> PostgreSQL (ext_{extension_id}.*)
-> Handler: V8 isolate -> ctx.db / ctx.fetch / ctx.secrets
-> Response serialized to JSON
-> postMessage back to extension

Rate limits

Function typeLimitApplies to
queryRows100 calls/minutePer installation
insertRow / patchRow / deleteRow50 calls/minutePer installation
query()100 calls/minutePer installation
mutation()50 calls/minutePer installation
action()20 calls/minutePer installation

Database isolation

Each extension gets its own isolated PostgreSQL schema: ext_\{extension_id\}. Tables defined in server/schema.ts live in this schema:

ext_88b2478a_39c7_468e_bebd_14e52fd97ac0.rules
ext_88b2478a_39c7_468e_bebd_14e52fd97ac0.votes

No extension can read or write another extension's tables. The Lumio API enforces this at the query level.

File structure

server/
├── schema.ts <- Table definitions (defineSchema + defineTable)
└── functions.ts <- Function exports (queryRows, action, etc.)

Both files are optional. An extension can have server: true but only use schema for useExtensionStorage() type safety, without defining custom functions.

When to use server functions

ScenarioRecommendation
Simple toggle / text settinguseExtensionStorage() — no server needed
List of items (rules, songs, votes)Declarative server functions + defineTable
Aggregations (count, sum, averages)Handler-based query()
External API calls (sports scores, weather)Handler-based action()
User-specific data (per-viewer state)Handler-based with ctx.auth.userId
Secrets (API keys)Handler-based action() with ctx.secrets