A modern authentication boilerplate for Next.js with BetterAuth, PostgreSQL (Prisma), Stripe, and Paddle.
- Next.js 16+ with App Router
- BetterAuth — credentials, Google, GitHub OAuth
- PostgreSQL via Prisma 7 (Neon, Supabase, or any Postgres)
- Stripe & Paddle payment integration
- OTP email verification via Nodemailer
- Rate limiting, dark/light mode, TypeScript, Tailwind CSS
- Node.js v20+
- pnpm v11+
- PostgreSQL database (Neon recommended)
git clone https://github.com/zeon-studio/authplate.git
cd authplate
pnpm installCopy the example file and fill in your values:
cp .env.example .env# Better Auth
BETTER_AUTH_SECRET="generate_a_random_secret"
BETTER_AUTH_URL="http://localhost:3000"
# OAuth
GITHUB_CLIENT_ID=""
GITHUB_CLIENT_SECRET=""
GOOGLE_CLIENT_ID=""
GOOGLE_CLIENT_SECRET=""
# Rate limiting
RATELIMIT_WINDOW=10
RATELIMIT_MAX=100
# Password hashing
SALT_ROUND=10
# Database (PostgreSQL)
DATABASE_URL="postgresql://user:password@host/dbname?sslmode=require"
# Nodemailer
SENDER_EMAIL="your@email.com"
EMAIL_PASSWORD="your_app_password"
# Stripe
NEXT_PUBLIC_STRIPE_PUBLIC_KEY=""
STRIPE_SECRET_KEY=""
STRIPE_WEBHOOK_SECRET=""
# Paddle
PADDLE_API_KEY=""
NEXT_PUBLIC_PADDLE_CLIENT_TOKEN=""
PADDLE_NOTIFICATION_WEBHOOK_SECRET=""
NEXT_PUBLIC_PADDLE_ENV="sandbox"Generate the Prisma client and push the schema to your database:
pnpm db:generate
pnpm db:pushpnpm devApp runs at http://localhost:3000.
Authplate uses PostgreSQL with Prisma 7. Any Postgres provider works. Neon is recommended for serverless deployments (free tier available).
| Command | Description |
|---|---|
pnpm db:generate |
Regenerate Prisma client from schema |
pnpm db:push |
Push schema to DB without migration files (dev/prototyping) |
pnpm db:migrate |
Create and apply a named migration (dev) |
pnpm db:migrate:prod |
Apply pending migrations (production deploys) |
pnpm db:studio |
Open Prisma Studio visual editor |
After editing prisma/schema.prisma:
# Development — creates a migration file + applies it
pnpm db:migrate
# Or push directly without migration files (prototyping only)
pnpm db:push
# Regenerate the Prisma client
pnpm db:generateThe generated client lives at
src/generated/prisma/(gitignored). Always runpnpm db:generateafter schema changes or a freshpnpm install.
BetterAuth handles all auth flows. Configure providers in src/lib/auth/auth.ts.
- Go to Google Cloud Console
- Create OAuth 2.0 credentials
- Add
http://localhost:3000/api/auth/callback/googleas redirect URI
- Go to GitHub Developer Settings
- Register a new OAuth App
- Set callback URL to
http://localhost:3000/api/auth/callback/github
Uses Nodemailer. For Gmail, create an App Password and use it as EMAIL_PASSWORD.
Configure pricing tiers in src/app/actions/paddle/pricing-tier.ts (Paddle) or src/config/stripe.ts (Stripe).
- Create a Paddle account
- Get
PADDLE_API_KEYandNEXT_PUBLIC_PADDLE_CLIENT_TOKENfrom the dashboard - Set up a webhook pointing to
https://yourdomain.com/api/paddlehooks - Copy the webhook secret to
PADDLE_NOTIFICATION_WEBHOOK_SECRET - Set
NEXT_PUBLIC_PADDLE_ENV=sandboxfor testing,productionfor live
- Get keys from the Stripe Dashboard
- Set up a webhook pointing to
https://yourdomain.com/api/stripe-hooks - Copy the webhook signing secret to
STRIPE_WEBHOOK_SECRET
Build:
docker build --build-arg DATABASE_URL="your_postgres_url" -t authplate .Run:
docker run -p 3000:3000 \
-e DATABASE_URL="..." \
-e BETTER_AUTH_SECRET="..." \
-e BETTER_AUTH_URL="https://yourdomain.com" \
-e GOOGLE_CLIENT_ID="..." \
-e GOOGLE_CLIENT_SECRET="..." \
-e GITHUB_CLIENT_ID="..." \
-e GITHUB_CLIENT_SECRET="..." \
-e SENDER_EMAIL="..." \
-e EMAIL_PASSWORD="..." \
-e PADDLE_API_KEY="..." \
-e NEXT_PUBLIC_PADDLE_CLIENT_TOKEN="..." \
-e PADDLE_NOTIFICATION_WEBHOOK_SECRET="..." \
-e NEXT_PUBLIC_PADDLE_ENV="production" \
authplate
DATABASE_URLis needed at build time (prisma generate) and at runtime. Pass it as both--build-argand-e.
MIT — see LICENSE.
Built by Zeon Studio