Introduction
Building authentication from scratch is complex—OAuth flows, session management, CSRF protection, secure cookies. Auth.js (formerly NextAuth.js) handles all of this for you, with first-class support for Next.js.
Key Concepts
Auth.js is a complete authentication solution:
- Providers: OAuth (Google, GitHub, etc.), Credentials (email/password), Email magic links
- Session handling: JWT or database sessions, automatic refresh
- Callbacks: Hook into the auth flow for customization
- Adapters: Store users in any database (Prisma, Drizzle, etc.)
Real World Context
Auth.js powers thousands of production apps because:
- OAuth is handled correctly (state, PKCE, token refresh)
- Security best practices are built-in
- Adding new providers takes minutes, not hours
- Session management just works
Deep Dive
Installation
bashnpm install next-auth@beta
Core Configuration
Create auth.ts in your project root:
typescript// auth.ts import NextAuth from 'next-auth'; import GitHub from 'next-auth/providers/github'; import Google from 'next-auth/providers/google'; export const { handlers, auth, signIn, signOut } = NextAuth({ providers: [ GitHub({ clientId: process.env.AUTH_GITHUB_ID, clientSecret: process.env.AUTH_GITHUB_SECRET, }), Google({ clientId: process.env.AUTH_GOOGLE_ID, clientSecret: process.env.AUTH_GOOGLE_SECRET, }), ], });
Route Handler Setup
Create app/api/auth/[...nextauth]/route.ts:
typescriptimport { handlers } from '@/auth'; export const { GET, POST } = handlers;
This single file creates all necessary endpoints:
GET /api/auth/signin- Sign-in pageGET /api/auth/signout- Sign-out pageGET /api/auth/session- Get current sessionGET /api/auth/csrf- CSRF tokenGET /api/auth/providers- List of providersPOST /api/auth/signin/:provider- Start OAuth flowGET /api/auth/callback/:provider- OAuth callback
Environment Variables
bash# .env.local AUTH_SECRET=your-random-secret-min-32-chars AUTH_GITHUB_ID=your-github-client-id AUTH_GITHUB_SECRET=your-github-client-secret AUTH_GOOGLE_ID=your-google-client-id AUTH_GOOGLE_SECRET=your-google-client-secret
Generate AUTH_SECRET:
bashnpx auth secret
Exports Overview
typescriptexport const { handlers, // GET and POST for route handler auth, // Get session (Server Components, API routes) signIn, // Programmatic sign-in signOut, // Programmatic sign-out } = NextAuth({ /* config */ });
Common Pitfalls
-
Missing AUTH_SECRET: Auth.js won't work without a secret. Generate one and add it to your environment.
-
Wrong callback URLs: OAuth providers need exact callback URLs. Use
http://localhost:3000/api/auth/callback/githubfor local development. -
Forgetting the route handler: The
[...nextauth]/route.tsfile must exist for Auth.js to function.
Best Practices
- Use environment variable prefixes:
AUTH_GITHUB_IDinstead ofGITHUB_IDfor clarity - Generate a strong secret: Use
npx auth secretto generate a cryptographically secure secret - Start with one provider: Get one working before adding more
- Check the console: Auth.js logs helpful debugging information
Summary
Auth.js provides production-ready authentication for Next.js with minimal setup. Install the package, create an auth config with your providers, set up the route handler, and you have OAuth, sessions, and security handled. The library exports auth(), signIn(), and signOut() for use throughout your application.