DEV Community

Atlas Whoff
Atlas Whoff

Posted on

Clerk vs NextAuth vs Auth.js: Which Auth Library for Your Next.js App

Clerk vs NextAuth vs Auth.js: Which Auth Library for Your Next.js App

Auth is the first thing you build and the hardest to change later. Three dominant options exist — here's when to use each.

The Options

Clerk — Managed auth service

Full authentication UI, user management dashboard, and SDKs. You pay for monthly active users.

Pros: Pre-built UI components, MFA, orgs/teams, user impersonation, zero backend code

Cons: $25+/mo at scale, vendor lock-in, less control

Use when: B2B SaaS where teams/orgs matter, or you want zero auth code

Auth.js (NextAuth v5) — Open source, self-hosted

The standard for Next.js auth. Social providers, credentials, JWTs or database sessions.

Pros: Free, open source, massive ecosystem, works with any database

Cons: You maintain it, less polished UI out of the box

Use when: Standard OAuth flows, want full control, cost matters

Better Auth — Newer open source alternative

Drop-in Clerk-like features with self-hosting: orgs, API keys, MFA, all included.

Pros: Most features, self-hosted, TypeScript-first

Cons: Younger ecosystem

Use when: Want Clerk features without the bill

Auth.js v5 Setup (Most Common)

npm install next-auth@beta @auth/prisma-adapter
Enter fullscreen mode Exit fullscreen mode
// auth.ts
import NextAuth from 'next-auth';
import { PrismaAdapter } from '@auth/prisma-adapter';
import Google from 'next-auth/providers/google';
import GitHub from 'next-auth/providers/github';
import { prisma } from './prisma';

export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: PrismaAdapter(prisma),
  providers: [Google, GitHub],
  callbacks: {
    session({ session, user }) {
      session.user.id = user.id;
      return session;
    },
  },
});
Enter fullscreen mode Exit fullscreen mode
// app/api/auth/[...nextauth]/route.ts
import { handlers } from '@/auth';
export const { GET, POST } = handlers;
Enter fullscreen mode Exit fullscreen mode

Protecting Routes

// middleware.ts — protect all /dashboard routes
import { auth } from '@/auth';

export default auth((req) => {
  if (!req.auth && req.nextUrl.pathname.startsWith('/dashboard')) {
    return Response.redirect(new URL('/login', req.url));
  }
});

export const config = { matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'] };
Enter fullscreen mode Exit fullscreen mode

Server Component Auth

import { auth } from '@/auth';
import { redirect } from 'next/navigation';

export default async function DashboardPage() {
  const session = await auth();
  if (!session) redirect('/login');

  return <div>Welcome, {session.user?.name}</div>;
}
Enter fullscreen mode Exit fullscreen mode

Prisma Schema

model User {
  id            String    @id @default(cuid())
  email         String    @unique
  name          String?
  accounts      Account[]
  sessions      Session[]
  plan          String    @default("free")
  createdAt     DateTime  @default(now())
}
model Account { ... } // Standard NextAuth fields
model Session { ... }
Enter fullscreen mode Exit fullscreen mode

Decision Summary

Need Choice
Teams/orgs, polished UI, fast setup Clerk
Standard OAuth, cost-conscious Auth.js
Clerk features, self-hosted Better Auth

Auth.js ships pre-configured (Google + GitHub + email) in the AI SaaS Starter Kit. $99 one-time at whoffagents.com.

Top comments (0)