36 lines | 2.0 KB

Auth.js / NextAuth v5 conventions

Central config

  • v5 centralizes setup in one auth.ts at the project root: export const { handlers, auth, signIn, signOut } = NextAuth({ providers: [...] }).
  • The App Router route handler just re-exports it: app/api/auth/[...nextauth]/route.tsexport const { GET, POST } = handlers.
  • Import providers from next-auth/providers/*. The npm package is next-auth; the project's brand is Auth.js.

One way to read the session

  • Use the universal auth() everywhere on the server — Server Components, route handlers, server actions, and middleware. It replaces getServerSession, getSession, getToken, and withAuth.
  • useSession() is for client components only, and requires a <SessionProvider> ancestor.

Secrets & providers

  • Read secrets from the environment: AUTH_SECRET is required. Provider credentials are auto-inferred from env (AUTH_GITHUB_ID / AUTH_GITHUB_SECRET, etc.) — don't hardcode them.

Sessions & adapters

  • For database sessions, use an official adapter from @auth/*-adapter (e.g. @auth/drizzle-adapter, @auth/prisma-adapter). Without an adapter, the default JWT session strategy applies.
  • Customize tokens/sessions only through the jwt and session callbacks. Keep them pure and minimal — no heavy I/O on every request.

Middleware

  • Protect routes by wrapping middleware.ts with auth.
  • Middleware runs on the edge. If your adapter or callbacks aren't edge-safe, split the config: put the edge-safe parts in auth.config.ts and import them into both auth.ts and middleware.ts.

Anti-patterns

  • ❌ Re-introducing getServerSession / getToken / withAuth instead of auth().
  • useSession() in server components, or without <SessionProvider>.
  • ❌ Hardcoded AUTH_SECRET / provider credentials.
  • ❌ Heavy logic or side effects inside the jwt / session callbacks.
  • ❌ Importing a non-edge adapter into edge middleware (split with auth.config.ts).