A full-stack authentication template built with Next.js, PostgreSQL (Neon), and NextAuth.js. This template provides a complete authentication system with email/password authentication, OAuth providers (Google and GitHub), email verification, and password reset functionality.
- 🔐 Multiple Authentication Methods
- Email/password authentication
- Google OAuth
- GitHub OAuth
- ✉️ Email Functionality
- Email verification on registration
- Password reset via email
- Transactional emails via Brevo
- 🗄️ Database
- PostgreSQL with Prisma ORM
- User management with roles (USER, ADMIN)
- Session and account management
- 🎨 Modern UI
- Built with React 19 and Next.js 15
- Tailwind CSS v4 for styling
- Shadcn/ui components
- Responsive design
- 🔒 Security
- Password hashing with bcryptjs
- Secure session management
- Protected routes with middleware
- Email verification required for login
Before you begin, ensure you have the following installed:
- Node.js (v18 or higher)
- npm or yarn or pnpm
- A PostgreSQL database (Neon recommended)
- A Google Cloud Console account (for Google OAuth)
- A GitHub account (for GitHub OAuth)
- A Brevo account (for email sending)
git clone <repository-url>
cd nextjs-auth-postgres-templatenpm install
# or
yarn install- Go to Neon and create a project
- Get your connection string from the Neon dashboard
- Install PostgreSQL locally following the official installation guide
- Start your PostgreSQL service
- Your connection string will be:
postgresql://user:password@localhost:5432/<database-name>
Create a .env.local file in the root directory of the project:
# Database
DATABASE_URL="your-postgres-connection-string"
# NextAuth Configuration
NEXTAUTH_URL="https://your-production-domain.com"
NEXTAUTH_SECRET="your-generated-secret-here"
# Application URL
NEXT_PUBLIC_APP_URL="https://your-production-domain.com"
# Google OAuth
GOOGLE_CLIENT_ID="your-google-client-id"
GOOGLE_CLIENT_SECRET="your-google-client-secret"
# GitHub OAuth
GITHUB_CLIENT_ID="your-github-client-id"
GITHUB_CLIENT_SECRET="your-github-client-secret"
# Brevo Email Service
BREVO_API_KEY="your-brevo-api-key"
EMAIL_FROM_NAME="Your App Name"
EMAIL_FROM_ADDRESS="noreply@yourdomain.com"You can generate a secure secret using one of these methods:
Using OpenSSL (recommended):
openssl rand -base64 32Using Node.js:
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"Online generator: Visit https://generate-secret.vercel.app/32
- Go to Google Cloud Console
- Create a new project or select an existing one
- Navigate to APIs & Services > Credentials
- Click "Create Credentials" > "OAuth client ID"
- If prompted, configure the OAuth consent screen:
- Choose "External" (unless you have a Google Workspace)
- Fill in the required information (App name, User support email, Developer contact)
- Add scopes:
email,profile - Add test users if needed
- Create OAuth client ID:
- Application type: "Web application"
- Name: Your application name
- Authorized JavaScript origins:
- For production:
https://your-production-domain.com - For development:
http://localhost:3000
- For production:
- Authorized redirect URIs:
- For production:
https://your-production-domain.com/api/auth/callback/google - For development:
http://localhost:3000/api/auth/callback/google
- For production:
- Copy the Client ID and Client Secret to your
.env.localfile
- Go to GitHub Developer Settings
- Click "New OAuth App"
- Fill in the application details:
- Application name: Your application name
- Homepage URL:
- For production:
https://your-production-domain.com - For development:
http://localhost:3000
- For production:
- Authorization callback URL:
- For production:
https://your-production-domain.com/api/auth/callback/github - For development:
http://localhost:3000/api/auth/callback/github
- For production:
- Click "Register application"
- Copy the Client ID
- Click "Generate a new client secret" and copy the secret
- Add both to your
.env.localfile
- Go to Brevo and create an account
- Navigate to Settings > SMTP & API
- Click on "API Keys" tab
- Click "Generate a new API key"
- Give it a name (e.g., "Next.js Auth Template")
- Copy the API key to your
.env.localfile asBREVO_API_KEY - Set
EMAIL_FROM_NAMEto your desired sender name (e.g., "My App") - Set
EMAIL_FROM_ADDRESSto a verified sender email address in Brevo:- Go to Settings > Senders
- Add and verify your sender email address
- Use this verified email in
EMAIL_FROM_ADDRESS
npx prisma generatenpx prisma db pushOr if you prefer to use migrations:
npx prisma migrate devnpm run dev
# or
yarn dev
# or
pnpm devOpen http://localhost:3000 in your browser to see the application.
| Variable | Description | Example |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string | postgresql://<username>:<password>@<host>:<port>/<database> |
NEXTAUTH_URL |
Base URL of your application (production) | https://yourdomain.com |
NEXTAUTH_SECRET |
Secret key for NextAuth (generate securely) | base64-encoded-random-string |
NEXT_PUBLIC_APP_URL |
Public URL of your application | https://yourdomain.com |
GOOGLE_CLIENT_ID |
Google OAuth Client ID | 123456789-abc.apps.googleusercontent.com |
GOOGLE_CLIENT_SECRET |
Google OAuth Client Secret | GOCSPX-xxxxxxxxxxxxx |
GITHUB_CLIENT_ID |
GitHub OAuth Client ID | Iv1.xxxxxxxxxxxxx |
GITHUB_CLIENT_SECRET |
GitHub OAuth Client Secret | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
BREVO_API_KEY |
Brevo API key for sending emails | xkeysib-xxxxxxxxxxxxx |
EMAIL_FROM_NAME |
Name displayed in email sender | My App |
EMAIL_FROM_ADDRESS |
Email address to send from (must be verified in Brevo) | noreply@yourdomain.com |
![important]
Important: All of the following environment variables will be automatically added to your Vercel project after a successful Neon → Vercel integration.
You do not need to manually create or configure them.
Environment Variables Automatically Added:
DATABASE_POSTGRES_URLDATABASE_POSTGRES_PRISMA_URLDATABASE_URL_UNPOOLEDDATABASE_POSTGRES_URL_NON_POOLINGDATABASE_PGHOSTDATABASE_POSTGRES_USERDATABASE_URLDATABASE_POSTGRES_PASSWORDDATABASE_POSTGRES_DATABASEDATABASE_PGPASSWORDDATABASE_PGDATABASEDATABASE_PGHOST_UNPOOLEDDATABASE_PGUSERDATABASE_POSTGRES_URL_NO_SSLDATABASE_POSTGRES_HOSTDATABASE_NEON_PROJECT_ID
DATABASE_URL="postgresql://user:pass@ep-random-123456.us-east-2.aws.neon.tech/neondb"
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="your-generated-secret"
NEXT_PUBLIC_APP_URL="http://localhost:3000"
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"
BREVO_API_KEY="your-brevo-api-key"
EMAIL_FROM_NAME="My App"
EMAIL_FROM_ADDRESS="noreply@yourdomain.com"When deploying to production (Vercel, Netlify, etc.), set these environment variables in your platform's dashboard:
- Use your production domain for
NEXTAUTH_URLandNEXT_PUBLIC_APP_URL - Ensure PostgreSQL network access allows your production server's IP
- Update OAuth redirect URIs to use your production domain
- Use a strong, randomly generated
NEXTAUTH_SECRET
nextjs-auth-postgres-template/
├── prisma/
│ └── schema.prisma # Prisma schema for PostgreSQL
├── src/
│ ├── app/ # Next.js App Router pages
│ │ ├── api/ # API routes
│ │ │ └── auth/ # Authentication API routes
│ │ └── auth/ # Authentication pages
│ ├── components/ # React components
│ │ ├── auth/ # Authentication components
│ │ └── ui/ # shadcn/ui components
│ ├── lib/ # Utility functions and configurations
│ │ ├── auth/ # NextAuth configuration
│ │ ├── constants/ # Application constants
│ │ ├── email/ # Email service (Brevo)
│ │ └── validations/ # Zod validation schemas
│ └── middleware.ts # Next.js middleware for route protection
└── public/ # Static assets
npm run dev- Start development server with Turbopacknpm run build- Build the application for productionnpm run start- Start the production servernpm run lint- Run ESLintnpm run format- Format code with Prettiernpm run format:check- Check code formattingnpx prisma generate- Generate Prisma Clientnpx prisma db push- Push schema changes to databasenpx prisma studio- Open Prisma Studio (database GUI)
- Registration: Users can register with email/password or OAuth (Google/GitHub)
- Email Verification: Email/password users receive a verification email
- Login: Users can log in with email/password (after verification) or OAuth
- Password Reset: Users can request a password reset via email
- Session Management: Sessions are managed via NextAuth.js with JWT strategy
⚠️ PostgreSQL Network Access: For production, restrict PostgreSQL access to specific IP addresses if possible- 🔐 NEXTAUTH_SECRET: Always use a strong, randomly generated secret
- 🔒 Environment Variables: Never commit
.env.localto version control - ✅ Email Verification: Email verification is required before users can log in with email/password
- 🛡️ Password Hashing: Passwords are hashed using bcryptjs before storage
- Verify your
DATABASE_URLis correct - Check that your IP address is allowed in Neon/PostgreSQL settings
- Ensure your PostgreSQL user has the correct permissions
- Verify redirect URIs match exactly (including protocol and trailing slashes)
- Check that client IDs and secrets are correct
- Ensure OAuth consent screen is properly configured (Google)
- Verify your Brevo API key is correct
- Check that
EMAIL_FROM_ADDRESSis verified in Brevo - Review Brevo dashboard for any errors or rate limits
- Push your code to GitHub
- Import your repository in Vercel
- Add "npx prisma generate && next build" under Build and Development
- Add all environment variables in the Vercel dashboard
- Deploy
The application can be deployed to any platform that supports Next.js:
- Netlify
- AWS Amplify
- Railway
- Render
Make sure to:
- Set all required environment variables
- Configure PostgreSQL network access for your server's IP
- Update OAuth redirect URIs to your production domain
Note: This is a template project. Make sure to customize it according to your needs, especially:
- Update
APP_NAMEinsrc/lib/constants/site.ts - Customize email templates in
src/lib/email/brevo.ts - Adjust authentication flows and user roles as needed
- Review and update security settings for production use