Next Starter Kit
Getting Started

Configuration

Complete guide to configuring environment variables and application settings

Configuration

This guide covers all environment variables and configuration options for the Next.js Full-Stack Starter Kit.

Environment Variables

All configuration is done through environment variables in the .env file.

Note: Security: Never commit your .env file to version control. Use .env.example as a template.

Required Configuration

These variables are essential for the application to run:

Database

DATABASE_URL="postgresql://user:password@host:5432/database?sslmode=require"

Description: PostgreSQL connection string

Options:

  • Neon: postgresql://user:password@ep-xxxxx.region.aws.neon.tech/neondb?sslmode=require
  • Supabase: Get from Project Settings > Database
  • Local: postgresql://postgres:password@localhost:5432/yourdb

Note: SSL Mode: Production databases usually require ?sslmode=require. Local databases may not need it.

For detailed instructions on switching between database providers (Neon, Supabase, Local), see the Database Providers Guide.

Authentication

BETTER_AUTH_SECRET="your-secret-key-here-min-32-characters"
BETTER_AUTH_URL="http://localhost:3000"
NEXT_PUBLIC_APP_URL="http://localhost:3000"

BETTER_AUTH_SECRET:

  • Generate with: openssl rand -base64 32
  • Must be at least 32 characters
  • Keep this secret and secure
  • Use different values for dev/staging/production

BETTER_AUTH_URL:

  • The base URL of your application
  • Used for authentication callbacks
  • Development: http://localhost:3000
  • Production: https://yourdomain.com

NEXT_PUBLIC_APP_URL:

  • Public-facing app URL
  • Exposed to the browser (starts with NEXT_PUBLIC_)
  • Used for generating links in emails
  • Should match BETTER_AUTH_URL

Admin Setup

FIRST_ADMIN_EMAIL="admin@example.com"

Description: Email address for the first admin user

Usage:

  1. Sign up with this email
  2. Run pnpm admin:setup
  3. User will be promoted to admin role

Note: Security: After creating your first admin, you can remove this variable or use the admin dashboard to manage roles.

OAuth Providers (Optional)

Google OAuth

GOOGLE_CLIENT_ID="your-google-client-id.apps.googleusercontent.com"
GOOGLE_CLIENT_SECRET="your-google-client-secret"

Setup:

  1. Go to Google Cloud Console
  2. Create or select a project
  3. Enable Google+ API
  4. Configure OAuth consent screen
  5. Create OAuth 2.0 credentials (Web application)
  6. Add authorized redirect URI:
    • Dev: http://localhost:3000/api/auth/callback/google
    • Prod: https://yourdomain.com/api/auth/callback/google

GitHub OAuth

GITHUB_CLIENT_ID="your-github-client-id"
GITHUB_CLIENT_SECRET="your-github-client-secret"

Setup:

  1. Go to GitHub Developer Settings
  2. Click "New OAuth App"
  3. Fill in details:
    • Homepage URL: http://localhost:3000
    • Authorization callback URL: http://localhost:3000/api/auth/callback/github
  4. Get Client ID and generate Client Secret

Email Configuration (Optional)

Choose one email provider for sending transactional emails:

EMAIL_PROVIDER="nodemailer"  # Options: nodemailer | resend | sendgrid | mailgun

Nodemailer (SMTP)

Default option, works with any SMTP server:

EMAIL_PROVIDER="nodemailer"
EMAIL_HOST="smtp.gmail.com"
EMAIL_PORT="587"
EMAIL_USER="your-email@gmail.com"
EMAIL_PASS="your-app-password"
EMAIL_SECURE="false"  # Use "true" for port 465
EMAIL_FROM="Your App <noreply@yourapp.com>"

Gmail Setup:

  1. Enable 2-factor authentication
  2. Generate an App Password
  3. Use the app password in EMAIL_PASS

Other SMTP Providers:

  • Outlook: smtp.office365.com:587
  • Yahoo: smtp.mail.yahoo.com:587
  • Custom SMTP: Use your provider's settings

Note: Gmail OAuth2 (alternative): bash GMAIL_CLIENT_ID="your-google-client-id" GMAIL_CLIENT_SECRET="your-google-client-secret" GMAIL_REFRESH_TOKEN="your-refresh-token"

Resend

Modern email API with great DX:

EMAIL_PROVIDER="resend"
RESEND_API_KEY="re_xxxxxxxxxxxx"
EMAIL_FROM="Your App <noreply@yourdomain.com>"

Setup:

  1. Create account at Resend
  2. Verify your domain
  3. Get API key from API Keys page

Pricing: 100 emails/day free, then $20/month for 50,000 emails

SendGrid

Popular email service by Twilio:

EMAIL_PROVIDER="sendgrid"
SENDGRID_API_KEY="SG.xxxxxxxxxxxx"
EMAIL_FROM="Your App <noreply@yourdomain.com>"

Setup:

  1. Create account at SendGrid
  2. Verify your domain
  3. Create API key in Settings > API Keys

Pricing: 100 emails/day free, then starts at $15/month

Mailgun

Reliable email service for developers:

EMAIL_PROVIDER="mailgun"
MAILGUN_API_KEY="your-mailgun-api-key"
MAILGUN_DOMAIN="mg.yourdomain.com"
MAILGUN_REGION="us"  # or "eu"
EMAIL_FROM="Your App <noreply@mg.yourdomain.com>"

Setup:

  1. Create account at Mailgun
  2. Add and verify your domain
  3. Get API key from Settings > API Keys

Pricing: 5,000 emails/month free for 3 months

Stripe (Optional)

For subscription payments and billing:

STRIPE_SECRET_KEY="sk_test_xxxxxxxxxxxx"
STRIPE_PUBLISHABLE_KEY="pk_test_xxxxxxxxxxxx"
STRIPE_WEBHOOK_SECRET="whsec_xxxxxxxxxxxx"

Setup:

  1. Create account at Stripe
  2. Get API keys from Dashboard > Developers > API keys
  3. Set up webhooks:
    • Go to Dashboard > Developers > Webhooks
    • Add endpoint: https://yourdomain.com/api/stripe/webhook
    • Select events: customer.subscription.*, invoice.*, payment_intent.*
    • Get webhook signing secret

Stripe Price IDs

Configure your product price IDs:

STRIPE_PRICE_PRO_MONTHLY="price_xxxxxxxxxxxx"
STRIPE_PRICE_PRO_YEARLY="price_xxxxxxxxxxxx"
STRIPE_PRICE_STARTUP_MONTHLY="price_xxxxxxxxxxxx"
STRIPE_PRICE_STARTUP_YEARLY="price_xxxxxxxxxxxx"

To get Price IDs:

  1. Create products in Stripe Dashboard > Products
  2. Add pricing (monthly and yearly)
  3. Copy the Price ID (starts with price_)

Note: Test Mode: Use test mode keys (starts with sk_test_ and pk_test_) during development. Switch to live keys in production.

File Uploads (Optional)

UploadThing

UPLOADTHING_TOKEN="eyJhcHBJZCI6xxxxxxxxxxxx"

Setup:

  1. Create account at UploadThing
  2. Create an app
  3. Copy token from Dashboard

Pricing: 2GB storage + 2GB bandwidth free, then pay-as-you-go

Features:

  • Automatic image optimization
  • CDN distribution
  • File type validation
  • Size limits

AI Writing Assistant (Optional)

OPENROUTER_API_KEY="sk-or-v1-xxxxxxxxxxxx"

Description: API key for AI-powered blog writing features

Setup:

  1. Create account at OpenRouter
  2. Get API key from Keys page
  3. Add credits (optional - free models available!)

Models Used:

  • Free models (no cost):
    • meta-llama/llama-3.2-3b-instruct:free
    • google/gemini-flash-1.5
  • Paid models (optional):
    • anthropic/claude-3.5-sonnet
    • openai/gpt-4-turbo

Note: Free Tier: The starter kit uses FREE models by default. No API costs!

Testing (Optional)

Pre-configured test user credentials for E2E tests:

TEST_USER_EMAIL="test-user@example.com"
TEST_USER_PASSWORD="TestUser123!@#"
TEST_ADMIN_EMAIL="test-admin@example.com"
TEST_ADMIN_PASSWORD="TestAdmin123!@#"

Usage: Run pnpm test:seed to create these test users, then use them in Playwright tests.

Additional Configuration

Node Environment

NODE_ENV="development"  # development | production

Auto-set by Next.js, but you can override if needed.

Rate Limiting

Rate limiting is configured in code (src/lib/rate-limit.ts), not environment variables. See Security > Rate Limiting for customization.

Security Headers

Security headers are configured in next.config.ts. See Security > Headers for details.

Configuration by Environment

Development (.env.local)

DATABASE_URL="postgresql://localhost:5432/mydb"
BETTER_AUTH_SECRET="dev-secret-change-me"
BETTER_AUTH_URL="http://localhost:3000"
NEXT_PUBLIC_APP_URL="http://localhost:3000"
FIRST_ADMIN_EMAIL="dev@example.com"

# Optional: Use test mode for services
STRIPE_SECRET_KEY="sk_test_..."
EMAIL_PROVIDER="nodemailer"

Staging

DATABASE_URL="postgresql://staging-db-url"
BETTER_AUTH_SECRET="staging-secret-32-chars-min"
BETTER_AUTH_URL="https://staging.yourdomain.com"
NEXT_PUBLIC_APP_URL="https://staging.yourdomain.com"

# Use test mode Stripe
STRIPE_SECRET_KEY="sk_test_..."

Production

DATABASE_URL="postgresql://production-db-url"
BETTER_AUTH_SECRET="production-secret-SUPER-SECURE"
BETTER_AUTH_URL="https://yourdomain.com"
NEXT_PUBLIC_APP_URL="https://yourdomain.com"

# Use live Stripe keys
STRIPE_SECRET_KEY="sk_live_..."
STRIPE_PUBLISHABLE_KEY="pk_live_..."

# Configure all integrations
GOOGLE_CLIENT_ID="..."
GITHUB_CLIENT_ID="..."
RESEND_API_KEY="..."
UPLOADTHING_TOKEN="..."

Environment Variable Validation

The starter kit validates required environment variables during setup. Run:

pnpm project:setup

This checks for:

  • ✅ Database connection
  • ✅ Auth secrets
  • ✅ Required URLs
  • ⚠️ Warns about missing optional configs

Security Best Practices

1. Never Commit Secrets

# .gitignore already includes:
.env
.env.local
.env*.local

2. Rotate Secrets Regularly

  • Change BETTER_AUTH_SECRET every 90 days
  • Rotate API keys periodically
  • Update passwords and tokens

3. Use Different Secrets Per Environment

Never reuse production secrets in development/staging.

4. Minimum Secret Length

  • BETTER_AUTH_SECRET: minimum 32 characters
  • Passwords: minimum 12 characters
  • API tokens: as provided by the service

5. Environment-Specific Configuration

# ✅ Good
# Each environment has unique values
BETTER_AUTH_SECRET="prod-abc123..."  # Production
BETTER_AUTH_SECRET="stag-xyz789..."  # Staging

# ❌ Bad
# Same secret in all environments

Troubleshooting

"Invalid environment variable" errors

  1. Check .env file exists
  2. Verify all required variables are set
  3. Ensure no extra spaces around =
  4. Restart dev server after changes

Database connection fails

  1. Verify DATABASE_URL format
  2. Check database is running
  3. Test SSL requirements (?sslmode=require)
  4. Verify credentials are correct

Auth redirects fail

  1. Ensure BETTER_AUTH_URL matches your domain
  2. Check trailing slashes (none should be present)
  3. Verify OAuth redirect URLs match exactly

Emails not sending

  1. Check email provider credentials
  2. Verify EMAIL_FROM domain is verified
  3. Test with a simple SMTP provider first
  4. Check application logs for errors

Next Steps

On this page