Configuration

Lucent is configured in lucent.config.ts with defineLucentConfig(...).

Use Environment as the canonical reference for env vars.

Minimal Example

import { defineLucentConfig } from "@codesordinatestudio/lucent";
import { Collections } from "./collections";

export default defineLucentConfig({
  db: {
    adapter: "postgres",
    url: process.env.DATABASE_URL,
  },
  auth: {
    strategies: ["jwt"],
    jwt: {
      secret: process.env.JWT_SECRET,
      accessTokenExpiry: "15m",
      refreshTokenExpiry: "7d",
    },
  },
  api: {
    prefix: "/api",
    cors: {
      origin: ["https://app.example.com"],
      credentials: true,
    },
  },
  collections: Collections,
  typegen: {
    output: "./lucent-types.ts",
  },
});

Core Config Sections

db

db: {
  adapter: "postgres",
  url: process.env.DATABASE_URL,
  pool: {
    max: 10,
  },
}

SurrealDB:

db: {
  adapter: "surrealdb",
  url: process.env.SURREAL_URL,
  namespace: process.env.SURREAL_NAMESPACE,
  database: process.env.SURREAL_DATABASE,
  auth: {
    username: process.env.SURREAL_USERNAME!,
    password: process.env.SURREAL_PASSWORD!,
  },
}

auth

auth: {
  strategies: ["jwt", "session", "apiKey"],
  jwt: {
    secret: process.env.JWT_SECRET,
    accessTokenExpiry: "15m",
    refreshTokenExpiry: "7d",
    cookies: {
      enabled: true,
      crossOrigin: true,
      domain: process.env.COOKIE_DOMAIN,
    },
  },
  session: {
    secret: process.env.SESSION_SECRET!,
    ttl: 60 * 60 * 24 * 7,
    store: "db",
  },
  apiKey: {
    header: "x-api-key",
  },
}

Notes:

  • JWT_SECRET must be at least 32 characters
  • SESSION_SECRET is required when session auth is enabled
  • If cors.credentials is true, cors.origin cannot be "*"

api

api: {
  prefix: "/api",
  cors: {
    origin: ["https://app.example.com"],
    credentials: true,
  },
}

migration

migration: {
  warnings: "development",
  dropOrphaned: false,
}
  • warnings controls whether orphan warnings are shown
  • dropOrphaned is destructive and should remain opt-in

See Migrations for the operator workflow.

typegen

typegen: {
  output: "./lucent-types.ts",
  customTypes: ["./src/types/shared.ts"],
}

openapi

openapi: {
  enabled: true,
  path: "/api/docs",
  title: "My API",
  version: "1.0.0",
}

email

SMTP:

email: {
  provider: "smtp",
  from: process.env.SMTP_FROM,
  provideConfig: {
    host: process.env.SMTP_HOST,
    port: 587,
    secure: false,
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS,
  },
}

Resend:

email: {
  provider: "resend",
  from: process.env.SMTP_FROM,
  provideConfig: {
    apiKey: process.env.RESEND_API_KEY,
  },
}

cache

cache: {
  url: process.env.REDIS_URL!,
  ttl: 60,
}

Only configure this when Redis is actually available.

securityHeaders

securityHeaders: {
  enabled: true,
  headers: {
    "X-Frame-Options": "SAMEORIGIN",
  },
}

Lucent applies sensible defaults when this section is omitted.

healthCheck

healthCheck: {
  enabled: true,
  path: "/health",
}

requestId

requestId: {
  enabled: true,
}

Optional Runtime Integrations

upload

upload: {
  provider: "local",
  dir: "./uploads",
  prefix: "/uploads",
  allowedTypes: ["image/*", "application/pdf"],
  maxSize: 10 * 1024 * 1024,
}

S3-backed storage:

upload: {
  provider: "s3",
  prefix: "/uploads",
  s3: {
    bucket: process.env.S3_BUCKET!,
    region: process.env.S3_REGION!,
    accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
    signedUrlExpiry: 3600,
  },
}

Google Drive storage:

upload: {
  provider: "googleDrive",
  prefix: "/uploads",
  googleDrive: {
    clientEmail: process.env.GOOGLE_DRIVE_CLIENT_EMAIL!,
    privateKey: process.env.GOOGLE_DRIVE_PRIVATE_KEY!,
    folderId: process.env.GOOGLE_DRIVE_FOLDER_ID!,
  },
}

Google Drive service-account uploads require a Google Workspace Shared drive folder, or domain-wide delegation to a Workspace user with Drive storage quota. folderId can be the raw folder ID or the folder URL.

secrets

secrets: {
  enabled: true,
  masterKey: Bun.env.LUCENT_SECRETS_KEY,
  keyVersion: "v1",
}

Lucent Secrets encrypts JSON payloads into the internal lucent_secrets table. Keep masterKey outside the database. If the master key is lost, existing secrets cannot be recovered.

globalHooks

globalHooks: {
  afterCreate: [
    async ({ collection, doc, user }) => {
      console.log("created", collection.slug, doc.id, user?.id);
    },
  ],
}

endpoints

endpoints: [myCustomEndpoint]

Custom endpoints mount after Lucent's built-in routes.

Production Guidance

  • Keep lucent.config.ts declarative; avoid baking environment-specific secrets into source
  • Use Environment for env setup
  • Use Production Checklist for deployment hardening