Skip to content

Better Auth

Use Better Auth when you want a self-hosted auth server with email/password (and optional plugins) and need ownerId from the Better Auth session (user.id or user.email).

  1. Copy examples/with-better-auth/.env.example:

    • DATABASE_URL
    • BETTER_AUTH_SECRET, BETTER_AUTH_URL
    • Model keys (optional)
  2. Install:

    Terminal window
    pnpm add better-auth
  3. Configure lib/auth.ts per the example (Email+Password baseline for CI).

app/api/arivie/route.ts
/* SPDX-License-Identifier: Apache-2.0 */
import { getArivieRuntimeForOwner } from "../../../arivie.config";
import { resolveOwnerId } from "../../../lib/resolve-owner";
import { assertAuthBypassAllowed } from "../../../lib/auth-bypass";
assertAuthBypassAllowed();
export async function POST(req: Request): Promise<Response> {
const ownerId = await resolveOwnerId(req);
const { arivie } = await getArivieRuntimeForOwner(ownerId);
return arivie.next.POST(req);
}
lib/resolve-owner.ts
/* SPDX-License-Identifier: Apache-2.0 */
import { headers } from "next/headers";
import { auth } from "./auth";
import { BYPASS_OWNER_ID, isAuthBypassRequest } from "./auth-bypass";
export async function resolveOwnerId(req: Request): Promise<string> {
if (isAuthBypassRequest(req)) {
return BYPASS_OWNER_ID;
}
const session = await auth.api.getSession({ headers: await headers() });
const user = session?.user;
if (user?.id != null && user.id.length > 0) {
return user.id;
}
if (user?.email != null && user.email.length > 0) {
return user.email;
}
return process.env.ARIVIE_OWNER_ID ?? "with-better-auth-owner";
}

Session lookup uses auth.api.getSession({ headers }); user.id is preferred, then user.email.

Terminal window
pnpm --filter with-better-auth dev

Canonical tree: arivie/examples/with-better-auth/.

Tested with better-auth ^1.6.11.