Server: createAuth
createAuth(options) builds the Better Auth instance
for email/password sign-up and sign-in, backed by the fusion-db Drizzle
schema. The consumer owns the singleton — you create it once and export it:
import { createAuth } from "@tikab-interactive/fusion-auth/server";
import { createAuthSession } from "@tikab-interactive/fusion-auth/session";
export const auth = createAuth({
// optional — each injects a feature core auth no longer imports:
// secondaryStorage: getSecondaryStorage(), // fusion-cache
// sendResetPassword: async ({ user, url }) => { /* … */ }, // fusion-mailer
// plugins: [ldapSignIn(), ...oidcPlugins()], // fusion-auth-enterprise
});
export const { getSession, requireSession } = createAuthSession(auth);Mount the handler on a catch-all route:
import { auth } from "#/lib/auth";
export const handler = (request: Request) => auth.handler(request);The injected options
Everything is optional. Omit it all and you get a working email/password setup; pass a capability and core auth wires it in without ever importing the package that provides it. Hover the result:
// No options → email/password only, in-memory rate limits, no reset email.
const = ();
| Option | Provided by | Omitted → |
|---|---|---|
secondaryStorage | fusion-cache (Valkey) | rate-limit counters fall back to per-process memory |
sendResetPassword | fusion-mailer | reset links are generated but never delivered |
plugins | fusion-auth-enterprise | no LDAP/OIDC — email/password only |
Plugins are composed after tanstackStartCookies(), so cookie handling is
always in place.
What the instance enables out of the box
- Email + password,
minPasswordLength: 8, withautoSignInafter sign-up. - Drizzle adapter over the
fusion-dbuser/session/account/verificationtables (provider: "pg"). - Two extra user fields, both server-controlled (
input: false):
// Shape of the extra fields fusion-auth adds to every user row.
const = {
: "u_abc",
: "andre@tikab.com",
: false, // server-set; gates admin-only server functions
: null as Date | null, // set → treated as anonymous everywhere
};
type = <typeof , "isSiteAdmin" | "deactivatedAt">;
deactivatedAt is enforced at the session choke point: once it is
set, existing cookies and API tokens stop authenticating immediately.
Environment
| Variable | Purpose |
|---|---|
BETTER_AUTH_SECRET | Required. Signing secret for sessions/cookies. |
BETTER_AUTH_URL | The canonical origin. Always trusted. |
TRUSTED_ORIGINS | Comma-separated extra origins allowed to drive the auth API (e.g. behind a proxy with another name). |
NODE_ENV | production turns rate limiting on by default. |
Rate limiting uses the injected secondaryStorage when present (counters shared
across instances) and falls back to per-process memory otherwise.