bunderstackbunderstack/ docs

Configuration

bunderstack declarations, runtime options, transports, adapters, and lifecycle

Application options

const backend = bunderstack({
  schema,
  database: {
    adapter: libsql(),
    url,
    authToken,
    migrations: './migrations',
  },
  access,
  auth,
  authResolver,
  storage,
  email,
  env,
  jobs: (j) => j.define({}),
  api,
  middleware: [instrumentation],
  background: { autoStart: true },
  rateLimit: { windowMs: 60_000, max: 100 },
  idempotency: { ttlMs: 86_400_000 },
  realtime: { bufferSize: 1_000, resumeSeconds: 300, redis },
  openapi: true,
})

const app = await backend.start()

schema and database.adapter are required. All validation slots accept Standard Schema. api takes your oRPC router — an object built from bases you declared with defineApi, or a callback receiving the framework builder. middleware applies oRPC middleware to every procedure in the graph, generated ones included; see Middleware. openapi serves the optional projection at /api/openapi.json. auth takes better-auth options directly, or a builder ({ db, env }) => BetterAuthConfig when database hooks need the app's own connection — see Auth.

Realtime transport

ConfigurationTransportIntended use
omitted or falsedisabledno subscriptions or publications
realtime: truememoryone application process
realtime: true plus REDIS_URLRedisseparate web and worker processes
realtime: { redis }Redisexplicit shared publisher configuration

bufferSize and resumeSeconds configure Publisher retention. Heartbeats and exponential reconnect belong to the client transport and require no application setting.

When a standalone worker uses the memory publisher, app.runWorker() rejects startup unless allowProcessLocalRealtime: true is explicit. This prevents silently publishing events that cannot reach another process.

Database adapters

ImportDialectOptional peerTypical URL
bunderstack/libsqlSQLite@libsql/clientfile:./data.db, libsql://…
bunderstack/bun-sqliteSQLitenonefile:./data.db, :memory:
bunderstack/pglitePostgres@electric-sql/pglitefile:./data.pglite, memory://
bunderstack/bun-sqlPostgresnonepostgres://…
bunderstack/postgres-jsPostgrespostgrespostgres://…

The adapter dialect must match the Drizzle schema. Import only the adapter you use so optional drivers stay outside the application dependency graph.

Email and storage adapters

Email defaults to the console provider in development. Use Resend directly or the optional SMTP adapter:

import { smtp } from 'bunderstack/email-smtp'

email: {
  from: 'My app <[email protected]>',
  provider: smtp({ url: process.env.SMTP_URL! }),
}

Storage may use a local directory or S3-compatible infrastructure. Buckets carry their own upload, access, and image-transform rules; see Storage.

Declaration and lifecycle

await app.close() stops background work and closes application-owned database and Publisher resources. app.status, app.signal, and app.backgroundRunning expose lifecycle state.

bunderstack() is synchronous and side-effect-free. Deployment tooling imports the exported backend and reads backend.manifest without opening database or Redis connections. backend.start({ env }) owns production runtime resources; backend.test() creates an isolated, lexically owned test fixture.

For test suites, declare reusable defaults and setup with backend.test.configure({ env, database, logs, setup }). A call to the returned factory may override its defaults; env and database are deep-merged. The value returned from setup is exposed as fixture.context, and fixture.defer(cleanup) attaches additional resources to the fixture lifecycle.

Common environment variables

VariablePurpose
DATABASE_URLselected database connection
DATABASE_AUTH_TOKENhosted libSQL authentication
AUTH_SECRETBetter Auth secret; required in production
REDIS_URLshared Publisher for split processes
RESEND_API_KEYResend provider
SMTP_URLoptional SMTP adapter
S3_BUCKET, S3_REGION, S3_ENDPOINTS3-compatible storage
BUNDERSTACK_ROLEall, web, or worker

On this page