AUTH STARTER · GETTING STARTED
Getting started
Clone, copy env, run two commands, sign up. The whole setup is under five minutes if you've got Postgres ready.
Prerequisites
- Node 20 or newer.
- Bun (npm install was slowing us down — we switched and never looked back).
- A Postgres database. Neon free tier is fastest to set up.
1. Clone & install
After you buy the template you get pushed to your own private GitHub repo. Yours forever — fork it, rename it, ship it.
git clone git@github.com:peal-dev/your-auth-starter.git
cd your-auth-starter
bun installYes, it has to be bun
package.json uses bun-specific fields and the lockfile is bun.lock. npm install will technically work but you'll fight subtle dependency resolution differences. Use bun.
2. Copy env, fill in the basics
Copy .env.example to .env.local. Only two values are strictly required to boot — everything else is optional.
cp .env.example .env.local# Required to boot:
DATABASE_URL="postgresql://..."
BETTER_AUTH_SECRET="$(openssl rand -base64 32)"
BETTER_AUTH_URL="http://localhost:3000"
NEXT_PUBLIC_APP_URL="http://localhost:3000"
# Optional — enable any time:
# GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET
# GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET
# RESEND_API_KEY / EMAIL_FROM
# TURNSTILE_SECRET_KEY / NEXT_PUBLIC_TURNSTILE_SITE_KEYBETTER_AUTH_SECRET must be 32+ chars
The Zod schema in src/lib/env.ts will refuse to boot otherwise. Use openssl rand -base64 32. Do NOT use "changeme" — and do NOT reuse the local secret in production.
3. Push the schema to your DB
In dev we use db:push (fastest, no migration files). In prod you'll generate + migrate. We cover that in the Database page.
bun run db:push4. Run it
bun devOpen http://localhost:3000. Click "Sign up". You should see the auth card with whichever methods you've enabled. If you haven't set OAuth keys yet, the social buttons won't render — that's the toggle system working as designed.
If you got this far, you're done
Email & password works without any optional env vars. You can sign up, sign in, sign out, reset password (logs to console without RESEND_API_KEY). Everything else is additive.