superapp
ReferenceServer API

createEngine Options

Complete configuration reference.

createEngine accepts a single configuration object and returns an engine instance. This page documents every available option.

import { createEngine } from '@superapp/backend'

const engine = createEngine({
  mode: 'programmatic',
  superapp_db: './superapp.db',
  connections: {
    main: { type: 'postgres', url: process.env.PG_URL! },
  },
})

Top-Level Options

OptionTypeDefaultDescription
mode'programmatic' | 'admin_ui''programmatic'Engine operation mode. programmatic = config in code, admin_ui = config in admin UI.
superapp_dbstring'./superapp.db'Path to the database where superapp stores its own internal tables (sessions, roles, audit logs, admin configuration). Local file path for SQLite or a Turso URL.
integrationsProvider[][]Database provider modules to load. Each provider adds support for a database type (postgres, mysql, sqlite, csv).
connectionsRecord<string, ConnectionConfig>{}Named database connections. Keys become table namespace prefixes (e.g., main.orders).
authAuthProviderundefinedAuthentication provider. If omitted, the engine runs in open mode (no auth).
permissionsRecord<string, Permission>{}Permission definitions. Keys must be snake_case slugs. Only used in programmatic mode.
rolesRecord<string, string[]>{}Role-to-permission mappings. Each key is a role name, value is an array of permission slugs.
actionsRecord<string, Action>{}Typed server-side functions callable by the client via POST /actions/{name}. Each action defines Zod input/output schemas and a run function. Access controlled through roles using the action_ prefix. See Actions.
masterKeystringundefinedMaster API key for admin access. Required for admin_ui mode and admin endpoints. Set via environment variable, never hardcode.
schemaEndpointSchemaEndpointConfig | booleanfalseEnable the GET /schema introspection endpoint. Set true for defaults or pass a config object.
duckdbDuckDBConfigSee belowDuckDB engine configuration.
limitsLimitsConfigSee belowQuery and rate limit constraints.
auditAuditConfigSee belowAudit logging configuration.
jwtJWTConfigSee belowJWT verification settings.
securitySecurityConfigSee belowCORS, CSP, and network security.

connections

Each connection maps a name to a database configuration. The connection name becomes the namespace for all tables in that database.

connections: {
  main: { type: 'postgres', url: 'postgres://localhost:5432/mydb' },
  warehouse: { type: 'mysql', url: 'mysql://localhost:3306/warehouse' },
  legacy: { type: 'sqlite', path: './legacy.db' },
  imports: { type: 'csv', directory: './data/imports/' },
}
TypeConfig Shape
postgres{ type: 'postgres', url: string }
mysql{ type: 'mysql', url: string }
sqlite{ type: 'sqlite', path: string }
csv{ type: 'csv', directory: string }

duckdb

Configure the DuckDB in-process engine.

OptionTypeDefaultDescription
maxMemorystring'256MB'Maximum memory DuckDB can use. Accepts units: '128MB', '1GB', etc.
threadsnumber2Number of CPU threads DuckDB can use for query execution.
queryTimeoutnumber30000Maximum query execution time in milliseconds. Queries exceeding this are killed.
poolSizenumber10Number of DuckDB connections in the pool. Each concurrent request uses one connection.
idleTimeoutnumber300000Time in milliseconds before idle connections are reclaimed. Default is 5 minutes.
duckdb: {
  maxMemory: '512MB',
  threads: 4,
  queryTimeout: 60_000,
  poolSize: 20,
  idleTimeout: 600_000,
}

limits

Query and rate limit constraints to prevent abuse and resource exhaustion.

OptionTypeDefaultDescription
maxLimitnumber10000Maximum number of rows a single query can return. Client limit values above this are capped.
maxIncludeDepthnumber3Maximum nesting depth for include (relation) joins. Prevents deeply nested relation chains.
maxFilterDepthnumber5Maximum nesting depth for filter conditions ($and, $or, $not). Prevents excessively complex filters.
maxFilterConditionsnumber50Maximum total number of filter conditions in a single query.
maxRequestBodySizestring'1mb'Maximum HTTP request body size. Accepts units: '512kb', '2mb', etc.
queryTimeoutnumber30000Query-level timeout in milliseconds. Separate from DuckDB's internal timeout.
rateLimitPerUsernumber200Maximum requests per minute per authenticated user.
rateLimitPerIPnumber500Maximum requests per minute per IP address. Applies to unauthenticated requests too.
limits: {
  maxLimit: 5000,
  maxIncludeDepth: 2,
  maxFilterDepth: 4,
  maxFilterConditions: 30,
  maxRequestBodySize: '2mb',
  queryTimeout: 15_000,
  rateLimitPerUser: 100,
  rateLimitPerIP: 300,
}

audit

Configure audit logging for queries, permission denials, and admin actions.

OptionTypeDefaultDescription
enabledbooleanfalseEnable or disable audit logging entirely.
logQuerybooleantrueLog the SQL statement that was executed.
logParamsbooleanfalseLog query parameters. Useful for debugging but may contain sensitive data.
logDurationbooleantrueLog query execution time in milliseconds.
logUserbooleantrueLog the authenticated user ID with each query.
logDeniedbooleantrueLog permission denial events. Useful for detecting unauthorized access attempts.
logAdminActionsbooleantrueLog admin UI actions (permission changes, connection edits, role assignments).
retentionstring'90d'Auto-delete audit logs older than this duration. Accepts '30d', '90d', '1y', etc.
piiRedactionbooleanfalseRedact PII (emails, phone numbers) from audit log entries.
audit: {
  enabled: true,
  logQuery: true,
  logParams: false,       // disable in production to avoid logging sensitive data
  logDuration: true,
  logUser: true,
  logDenied: true,
  logAdminActions: true,
  retention: '90d',
  piiRedaction: true,
}

jwt

JWT verification settings. These configure how the auth provider validates incoming tokens.

OptionTypeDefaultDescription
algorithmsstring[]['HS256']Allowed JWT signing algorithms. Common values: 'HS256', 'RS256', 'ES256'.
issuerstringundefinedExpected JWT issuer (iss claim). If set, tokens with a different issuer are rejected.
audiencestringundefinedExpected JWT audience (aud claim). If set, tokens with a different audience are rejected.
clockSkewSecondsnumber5Allowed clock skew in seconds for expiration checks. Accounts for time differences between servers.
jwt: {
  algorithms: ['RS256', 'ES256'],
  issuer: 'https://auth.myapp.com',
  audience: 'https://api.myapp.com',
  clockSkewSeconds: 10,
}

security

Network security, CORS, and access control settings.

OptionTypeDefaultDescription
corsCorsConfigundefinedCORS configuration. If omitted, CORS headers are not set.
cors.originstring | string[]undefinedAllowed origins. Use an array for multiple domains. Never use '*' in production.
cors.credentialsbooleanfalseWhether to include Access-Control-Allow-Credentials: true.
cors.maxAgenumber86400Preflight cache duration in seconds.
cspstringundefinedContent-Security-Policy header value. Applied to admin UI responses.
adminIpAllowliststring[]undefinedIP addresses allowed to access admin endpoints. If set, all other IPs are blocked from /admin.
security: {
  cors: {
    origin: ['https://myapp.com', 'https://admin.myapp.com'],
    credentials: true,
    maxAge: 86400,
  },
  csp: "default-src 'self'; script-src 'self'",
  adminIpAllowlist: ['10.0.0.0/8', '192.168.1.0/24'],
}

schemaEndpoint

Enable the GET /schema endpoint for schema introspection.

// Boolean shorthand — enable with defaults
schemaEndpoint: true

// Object form — customize
schemaEndpoint: {
  enabled: true,
  token: process.env.SCHEMA_API_TOKEN,  // require a token for access
}
OptionTypeDefaultDescription
enabledbooleanfalseEnable the /schema endpoint.
tokenstringundefinedIf set, the endpoint requires this token in the Authorization header.

Full Example

import { createEngine } from '@superapp/backend'
import { betterAuthProvider } from '@superapp/backend/auth/better-auth'
import { postgresProvider } from '@superapp/backend/integrations/postgres'
import { mysqlProvider } from '@superapp/backend/integrations/mysql'

const engine = createEngine({
  mode: 'programmatic',
  superapp_db: process.env.TURSO_URL ?? './superapp.db',
  integrations: [postgresProvider, mysqlProvider],
  connections: {
    main: { type: 'postgres', url: process.env.PG_URL! },
    warehouse: { type: 'mysql', url: process.env.MYSQL_URL! },
  },
  auth: betterAuthProvider({
    secret: process.env.AUTH_SECRET!,
    userTable: {
      table: 'main.users',
      matchOn: { column: 'id', jwtField: 'id' },
      columns: ['id', 'email', 'name'],
    },
  }),
  duckdb: {
    maxMemory: '512MB',
    threads: 4,
    queryTimeout: 30_000,
    poolSize: 20,
    idleTimeout: 300_000,
  },
  limits: {
    maxLimit: 10_000,
    maxIncludeDepth: 3,
    maxFilterDepth: 5,
    maxFilterConditions: 50,
    maxRequestBodySize: '1mb',
    queryTimeout: 30_000,
    rateLimitPerUser: 200,
    rateLimitPerIP: 500,
  },
  audit: {
    enabled: true,
    logQuery: true,
    logParams: false,
    logDuration: true,
    logUser: true,
    logDenied: true,
    logAdminActions: true,
    retention: '90d',
    piiRedaction: true,
  },
  jwt: {
    algorithms: ['RS256'],
    issuer: 'https://auth.myapp.com',
    audience: 'https://api.myapp.com',
    clockSkewSeconds: 5,
  },
  security: {
    cors: {
      origin: ['https://myapp.com'],
      credentials: true,
    },
    adminIpAllowlist: ['10.0.0.0/8'],
  },
  masterKey: process.env.SUPERAPP_MASTER_KEY!,
  schemaEndpoint: {
    enabled: true,
    token: process.env.SCHEMA_API_TOKEN,
  },
  permissions: {
    view_own_orders: {
      name: 'View own orders',
      table: 'main.orders',
      operations: { select: true },
      columns: ['id', 'amount', 'status', 'created_at'],
      filter: { customer_id: { $eq: '$user.customer_id' } },
    },
  },
  actions: {
    incrementStock: {
      input: z.object({ productId: z.string(), amount: z.number().positive() }),
      output: z.object({ id: z.string(), stock: z.number() }),
      run: async ({ user, db }, { productId, amount }) => {
        const [updated] = await db
          .update(products)
          .set({ stock: sql`stock + ${amount}` })
          .where(eq(products.id, productId))
          .returning({ id: products.id, stock: products.stock })
        return updated
      },
    },
  },
  roles: {
    viewer: ['view_own_orders'],
    warehouse_manager: ['view_own_orders', 'action_incrementStock'],
  },
})

On this page