webdev.complete
🪪 Auth: NextAuth & Better Auth
🟢The Backend
Lesson 76 of 117
30 min

Auth.js (NextAuth v5)

Setup, providers, session strategies, adapters.

Auth.js (formerly NextAuth.js) is the most-installed auth library in the Next.js world. v5 cleaned up the API, dropped support for legacy runtimes, and embraced the App Router. In ten minutes you can have email, Google, GitHub, and Discord login working with sessions, CSRF, and cookies all handled for you.

Install & secrets

bash
pnpm add next-auth@beta
npx auth secret  # writes AUTH_SECRET to .env.local

Every provider also needs its own client ID and secret in .env.local:

.env.local
AUTH_SECRET=your-generated-secret
AUTH_GITHUB_ID=Iv1.xxx
AUTH_GITHUB_SECRET=xxx
AUTH_GOOGLE_ID=xxx.apps.googleusercontent.com
AUTH_GOOGLE_SECRET=xxx

The auth.ts hub

One file exports everything: the handlers for the route, the auth() function to read the session on the server, and signIn/signOut for client/server actions.

auth.ts
import NextAuth from "next-auth";
import GitHub from "next-auth/providers/github";
import Google from "next-auth/providers/google";
import { PrismaAdapter } from "@auth/prisma-adapter";
import { prisma } from "@/server/db";

export const { handlers, signIn, signOut, auth } = NextAuth({
  adapter: PrismaAdapter(prisma),
  providers: [GitHub, Google],
  session: { strategy: "database" },
  callbacks: {
    session({ session, user }) {
      session.user.id = user.id;
      return session;
    },
  },
});

Wire up the route handler

app/api/auth/[...nextauth]/route.ts
export { GET, POST } from "@/auth/handlers";
// Or, if you exported handlers from auth.ts:
// export { GET, POST } from "@/auth";

Session strategies: JWT vs database

  • JWT (default): session lives entirely in a signed cookie. No DB lookup per request. You cannot easily revoke. Great for edge runtimes.
  • Database: session row stored via an adapter. Requires a DB call per request but is revocable and trivially extensible. Pairs naturally with Prisma/Drizzle.
Pick database if you need to log users out
Killing a user's session means deleting that row. With JWT you have to wait for the token to expire (or maintain a denylist).

Reading the session in a Server Component

app/dashboard/page.tsx
import { auth } from "@/auth";
import { redirect } from "next/navigation";

export default async function Dashboard() {
  const session = await auth();
  if (!session) redirect("/login");
  return <h1>Hi, {session.user.name}</h1>;
}

Protecting groups of routes with proxy.ts

Next.js 16 deprecated the middleware.ts file convention and renamed it to proxy.ts. The behaviour is identical; the file name and the exported function name changed. Put the file at the project root, next to app/.

proxy.ts
export { auth as proxy } from "@/auth";

export const config = {
  matcher: ["/dashboard/:path*", "/account/:path*"],
};
There is a codemod
On an existing project, run npx @next/codemod@canary middleware-to-proxy . instead of renaming by hand.

Sign in & out

tsx
// Server Action
"use server";
import { signIn, signOut } from "@/auth";

export async function loginWithGitHub() {
  await signIn("github", { redirectTo: "/dashboard" });
}

export async function logout() {
  await signOut({ redirectTo: "/" });
}

Adapters

Adapters connect Auth.js to a database. The most common in 2026:

  • @auth/prisma-adapter
  • @auth/drizzle-adapter
  • @auth/supabase-adapter, plus adapters for Mongo, Firebase, Convex, Neon, Turso, etc.

Each adapter expects a few tables (User, Account, Session, VerificationToken). The Prisma adapter has the schema in its README, copy-paste it.

Read this before you pick Auth.js
In September 2025 the Auth.js maintainers handed the project over: it is now maintained and overseen by the Better Auth team, who have said they will keep shipping security patches and urgent fixes but recommend new projects start with Better Auth instead. There is a second thing to know. Auth.js v5 has been in beta for years; on npm, next-auth@latest still resolves to the v4 line, and v5 is only on the beta tag. Everything in this lesson is v5 API, which means you are installing a beta. That is fine for a codebase already on it, and a real consideration for a new one.

Quiz

Quiz1 / 3

What does `npx auth secret` do?

Recap

  • Install next-auth@beta, run npx auth secret, add provider env vars.
  • Centralize everything in auth.ts: exports handlers, auth, signIn, signOut.
  • JWT sessions are stateless and edge-friendly. Database sessions are revocable and richer.
  • Adapters wire Auth.js to your DB. Prisma and Drizzle are the most common.
  • Protect server components with await auth() + redirect; protect groups of routes via middleware.
Built with Next.js, Tailwind & Sandpack.
Learn. Build. Ship.