π A complete, production-ready authentication solution for Next.js applications
Stop building authentication from scratch. NexAuth is a comprehensive starter kit that provides everything you need to add secure authentication to your Next.js project in minutes, not days.
NexAuth is a battle-tested authentication boilerplate built with modern web technologies. It's designed for developers who want to:
- β Skip the tedious authentication setup
- β Start with production-ready security features
- β Focus on building their unique product features
- β Learn authentication best practices
Perfect for: SaaS applications, admin dashboards, customer portals, internal tools, and any Next.js project requiring user authentication.
- Email/Password Login - Traditional credentials-based authentication
- OAuth Integration - Sign in with Google and GitHub (easily extensible)
- Two-Factor Authentication (2FA) - Email-based OTP for enhanced security
- Email Verification - Verify user emails before account activation
- Password Reset - Secure password recovery flow with token expiration
- bcrypt Password Hashing - Industry-standard password encryption
- JWT Session Management - Stateless, scalable session handling
- Role-Based Access Control (RBAC) - Admin and User roles out of the box
- Protected Routes - Automatic authentication checks via middleware
- Token Expiration - All tokens expire after 1 hour for security
- User Registration - Complete signup flow with validation
- Profile Management - Users can update their information
- Account Settings - Enable/disable 2FA, change password, update email
- Admin Dashboard - Example admin-only pages and API routes
- Radix UI Components - 30+ accessible, customizable components
- Tailwind CSS 4 - Utility-first styling with dark mode support
- Responsive Design - Mobile-first, works on all devices
- Toast Notifications - User feedback with Sonner
- Form Validation - Real-time validation with React Hook Form & Zod
- Loading States - Smooth UX with spinners and transitions
Before you begin, ensure you have:
- Node.js 20+ installed (Download)
- PostgreSQL database (local or cloud - see Database Setup)
- Resend account for emails (Sign up free)
- (Optional) Google/GitHub OAuth credentials
# Clone the repository
git clone https://github.com/yourusername/nexauth.git
cd nexauth
# Install dependencies
npm installCreate a .env file in the root directory:
# Database Connection
DATABASE_URL="postgresql://user:password@localhost:5432/nexauth?schema=public"
# NextAuth Configuration
AUTH_SECRET="your-secret-key-here" # Generate with: openssl rand -base64 32
AUTH_URL="http://localhost:3000"
# Application URL (for email links)
NEXT_PUBLIC_APP_URL="http://localhost:3000"
# Email Service (Resend)
RESEND_API_KEY="re_xxxxxxxxxxxx" # Get from https://resend.com/api-keys
# OAuth Providers (Optional - see OAuth Setup below)
GOOGLE_CLIENT_ID="your-google-client-id"
GOOGLE_CLIENT_SECRET="your-google-client-secret"
GITHUB_CLIENT_ID="your-github-client-id"
GITHUB_CLIENT_SECRET="your-github-client-secret"π Generate AUTH_SECRET:
openssl rand -base64 32# Generate Prisma Client
npx prisma generate
# Run database migrations (creates all tables)
npx prisma migrate dev --name init
# (Optional) Open Prisma Studio to view your database
npx prisma studionpm run devOpen http://localhost:3000 in your browser. You're ready to go! π
-
Navigate to Registration
- Go to
http://localhost:3000/auth/register - Fill in your name, email, and password (minimum 6 characters)
- Click "Register"
- Go to
-
Verify Your Email
- Check your email inbox for a verification link
- Click the link to verify your account
- You'll be redirected to the login page
-
Log In
- Go to
http://localhost:3000/auth/login - Enter your email and password
- Click "Login"
- You'll be redirected to
/settings(the default protected page)
- Go to
- Log in to your account
- Navigate to
/settings - Toggle "Two-Factor Authentication" to ON
- On your next login, you'll receive a 6-digit code via email
- Enter the code to complete login
- Set up OAuth providers (see OAuth Setup)
- Go to
/auth/login - Click "Continue with Google" or "Continue with GitHub"
- Authorize the application
- You'll be automatically logged in (email is auto-verified for OAuth users)
All routes under app/(protected)/ require authentication:
app/(protected)/
βββ (routes)/
β βββ admin/ # Only accessible by ADMIN role
β βββ client/ # Example client page
β βββ server/ # Example server page
β βββ settings/ # User settings (default redirect after login)
Try it:
- Log out (if logged in)
- Try to access
http://localhost:3000/settings - You'll be automatically redirected to
/auth/login
-
Manually set a user as admin (in database):
npx prisma studio
- Open the
userstable - Find your user
- Change
rolefromUSERtoADMIN
- Open the
-
Access admin routes:
- Navigate to
/admin(only visible to admins) - Try the admin API endpoint
- Navigate to
nexauth/
βββ app/ # Next.js App Router
β βββ (protected)/ # π Protected routes (requires login)
β β βββ (routes)/ # Your protected pages
β β β βββ admin/ # Admin-only pages
β β β βββ settings/ # User settings page
β β β βββ ... # Add your pages here
β β βββ layout.tsx # Protected layout wrapper
β β
β βββ auth/ # π Authentication pages
β β βββ (routes)/
β β β βββ login/ # Login page
β β β βββ register/ # Registration page
β β β βββ reset/ # Password reset request
β β β βββ new-password/ # Set new password
β β β βββ new-verification/ # Email verification
β β βββ layout.tsx # Auth layout
β β
β βββ api/ # API routes
β β βββ admin/ # Admin API endpoints
β β βββ auth/[...nextauth]/ # NextAuth API handler
β β
β βββ layout.tsx # Root layout
β βββ page.tsx # Home page (public)
β
βββ actions/ # π― Server Actions (business logic)
β βββ login.ts # Login logic
β βββ register.ts # Registration logic
β βββ logout.ts # Logout logic
β βββ reset.ts # Password reset request
β βββ new-password.ts # Password update
β βββ new-verification.ts # Email verification
β βββ settings.ts # User settings update
β βββ admin.ts # Admin actions
β
βββ components/ # React components
β βββ auth/ # Authentication components
β β βββ login-form.tsx # Login form
β β βββ register-form.tsx # Registration form
β β βββ google.tsx # Google OAuth button
β β βββ github.tsx # GitHub OAuth button
β β βββ ... # Other auth components
β β
β βββ ui/ # π¨ Reusable UI components (30+)
β βββ button.tsx # Button component
β βββ input.tsx # Input component
β βββ card.tsx # Card component
β βββ ... # All Radix UI components
β
βββ data/ # πΎ Data Access Layer
β βββ user.ts # User queries
β βββ account.ts # Account queries
β βββ verification-token.ts # Verification token queries
β βββ password-reset-token.ts # Password reset queries
β βββ two-factor-*.ts # 2FA queries
β
βββ hooks/ # Custom React hooks
β βββ use-current-user.ts # Get current user
β βββ use-current-role.ts # Get current user role
β βββ use-mobile.ts # Mobile detection
β
βββ lib/ # π οΈ Utilities
β βββ prisma.ts # Prisma client instance
β βββ auth.ts # Auth helper functions
β βββ mail.ts # Email sending utility
β βββ tokens.ts # Token generation
β βββ utils.ts # General utilities
β
βββ prisma/ # Database
β βββ schema.prisma # Database schema
β
βββ schemas/ # Validation schemas
β βββ index.ts # Zod schemas for forms
β
βββ auth.config.ts # NextAuth provider config
βββ auth.ts # NextAuth main config
βββ routes.ts # Route access control
βββ middleware.ts # (Optional) Add your middleware
// app/(protected)/(routes)/dashboard/page.tsx
import { currentUser } from "@/lib/auth";
export default async function DashboardPage() {
const user = await currentUser();
return (
<div>
<h1>Welcome, {user?.name}!</h1>
{/* Your dashboard content */}
</div>
);
}// app/api/admin/users/route.ts
import { currentRole } from "@/lib/auth";
import { NextResponse } from "next/server";
export async function GET() {
const role = await currentRole();
if (role !== "ADMIN") {
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
}
// Your admin logic here
return NextResponse.json({ users: [] });
}"use client";
import { useCurrentUser } from "@/hooks/use-current-user";
export function UserProfile() {
const user = useCurrentUser();
return <div>Hello, {user?.name}</div>;
}- Install the provider package (if needed)
- Add credentials to
.env - Update
auth.config.ts:
import LinkedIn from "next-auth/providers/linkedin";
export default {
providers: [
// ... existing providers
LinkedIn({
clientId: process.env.LINKEDIN_CLIENT_ID,
clientSecret: process.env.LINKEDIN_CLIENT_SECRET,
}),
],
} satisfies NextAuthConfig;# macOS
brew install postgresql
brew services start postgresql
createdb nexauth
# Ubuntu/Debian
sudo apt-get install postgresql
sudo service postgresql start
sudo -u postgres createdb nexauth
# Windows
# Download from https://www.postgresql.org/download/windows/
# Use pgAdmin to create databaseUpdate .env:
DATABASE_URL="postgresql://postgres:password@localhost:5432/nexauth?schema=public"Vercel Postgres:
# Install Vercel CLI
npm i -g vercel
# Create database
vercel postgres create
# Copy connection string to .envSupabase:
- Go to supabase.com
- Create a new project
- Go to Settings β Database
- Copy the connection string
- Add to
.env
Neon:
- Go to neon.tech
- Create a new project
- Copy the connection string
- Add to
.env
- Go to Google Cloud Console
- Create a new project (or select existing)
- Navigate to APIs & Services β Credentials
- Click Create Credentials β OAuth 2.0 Client ID
- Configure consent screen if prompted
- Application type: Web application
- Add authorized redirect URI:
http://localhost:3000/api/auth/callback/google - Copy Client ID and Client Secret to
.env
- Go to GitHub Settings
- Click OAuth Apps β New OAuth App
- Fill in:
- Application name: Your app name
- Homepage URL:
http://localhost:3000 - Authorization callback URL:
http://localhost:3000/api/auth/callback/github
- Click Register application
- Copy Client ID and generate Client Secret
- Add both to
.env
- Go to resend.com
- Sign up for a free account
- Verify your domain (or use their test domain for development)
- Go to API Keys β Create API Key
- Copy the key to
.envasRESEND_API_KEY
Free tier includes: 100 emails/day, 3,000 emails/month
| Command | Description |
|---|---|
npm run dev |
Start development server on http://localhost:3000 |
npm run build |
Build for production |
npm run start |
Start production server |
npm run lint |
Run ESLint to check code quality |
npx prisma generate |
Generate Prisma Client after schema changes |
npx prisma migrate dev |
Create and apply a new database migration |
npx prisma migrate deploy |
Apply migrations in production |
npx prisma studio |
Open Prisma Studio (database GUI) |
npx prisma db push |
Push schema changes without migrations (dev only) |
-
Push your code to GitHub
git init git add . git commit -m "Initial commit" git remote add origin https://github.com/yourusername/your-repo.git git push -u origin main
-
Import to Vercel
- Go to vercel.com
- Click Import Project
- Select your GitHub repository
- Vercel will auto-detect Next.js
-
Add Environment Variables
- In Vercel dashboard, go to Settings β Environment Variables
- Add all variables from your
.envfile - Update
AUTH_URLandNEXT_PUBLIC_APP_URLto your production domain
-
Set up Database
- Use Vercel Postgres, Supabase, or Neon
- Update
DATABASE_URLin Vercel environment variables
-
Update OAuth Callback URLs
- In Google/GitHub OAuth settings, add production callback URLs:
https://yourdomain.com/api/auth/callback/google https://yourdomain.com/api/auth/callback/github
- In Google/GitHub OAuth settings, add production callback URLs:
-
Deploy
- Click Deploy
- Vercel will build and deploy your app
# Run migrations in production
npx prisma migrate deploySolution:
npx prisma generate
npm run devCause: Database schema not migrated
Solution:
npx prisma migrate devChecklist:
- β
RESEND_API_KEYis set correctly - β
NEXT_PUBLIC_APP_URLmatches your domain - β Email domain is verified in Resend (or using test domain)
Cause: Email already registered with credentials
Solution: Users must log in with the original method. To link accounts, implement account linking in settings.
Checklist:
- β
AUTH_SECRETis set - β Cookies are enabled in browser
- β
AUTH_URLmatches your domain
Solution:
npx prisma generate- Server Actions: All authentication logic is in
actions/- study these to understand the flows - Data Layer: Check
data/to see how database queries are abstracted - Validation: Look at
schemas/index.tsto see Zod validation patterns - Auth Config: Read
auth.tsandauth.config.tsto understand NextAuth setup
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Built with amazing open-source technologies:
- Next.js by Vercel
- NextAuth.js by the Auth.js team
- Prisma by Prisma
- Radix UI by WorkOS
- Tailwind CSS by Tailwind Labs
- π§ Email: saeedaltout25@gmail.com
Built with β€οΈ using Next.js and NextAuth.js
Star β this repo if you find it helpful!