llms.txt
llms.txt

Better Auth Integration

2 min read

Use Better Auth when the app should own its auth database, methods, plugins, and session policy. Farm mounts the Better Auth handler, while Better Auth remains the source of truth for the auth API.

Add Better Auth

farm add integration better-auth --ui

Install better-auth plus the database driver or adapter selected by the application.

Create the server instance

src/lib/auth.ts
import { betterAuth } from "better-auth";export const auth = betterAuth({  secret: process.env.BETTER_AUTH_SECRET,  baseURL: process.env.BETTER_AUTH_URL,  emailAndPassword: {    enabled: true,  },});

Configure the production database, social providers, plugins, and callbacks in this object. They are not duplicated in Farm config.

Register it

src/lib/integrations.ts
import { betterAuth } from "@farmjs/integrations/better-auth";import { auth } from "./auth";export const appIntegrations = {  auth: betterAuth({    instance: auth,  }),} as const;

Farm mounts the instance handler for both methods:

GET  /api/auth/[...auth]POST /api/auth/[...auth]

There is no app-local src/app/api/auth/[...auth]/route.ts file to maintain.

Create the browser client

src/lib/auth-client.ts
import { createAuthClient } from "better-auth/react";export const authClient = createAuthClient({  baseURL: "",});

An empty baseURL keeps browser calls on the current Farm origin.

Use Better Auth

const result = await authClient.signIn.email({  email: "ada@example.com",  password: "correct-horse-battery-staple",});
const session = await authClient.getSession();await authClient.signOut();

The available methods and response types come from Better Auth and its plugins. Farm does not generate a parallel api.auth caller tree for the catch-all handler.

Protect application routes

betterAuth(...) does not accept protectedRoutes. Read the session with Better Auth in server code or call the instance from Farm middleware, then apply your app's authorization rules.

For client-only guards, wait for authClient.getSession() before rendering private data, but keep sensitive authorization on the server.

What Farm owns

Farm Better Auth
Registers the integration in farm.config.ts. Defines users, accounts, sessions, and verification records.
Mounts GET and POST on /api/auth/[...auth]. Routes each auth action inside the catch-all handler.
Adds integration logging around mounted requests. Owns adapters, providers, plugins, callbacks, and cookies.
Removes the need for a manual route module. Supplies the React client and server APIs.

Adapter options

Option Required Use
instance Yes Better Auth instance with a handler(request) method.
log No Farm integration lifecycle and route logger.

Production checklist

  • Set a strong BETTER_AUTH_SECRET and the public BETTER_AUTH_URL.
  • Configure a persistent production database and run Better Auth migrations.
  • Keep database and OAuth credentials server-only.
  • Verify trusted origins, cookies, and proxy headers on the deployed origin.
  • Test sign-up, sign-in, session reads, sign-out, provider callbacks, and every enabled plugin.