BetterStarter logoBetterStarter
GuidesAuth

OTP (Email Sign-in)

Set up email OTP authentication — no passwords required.

Docs are in beta — content is improving rapidly. Found something missing? Open an issue on GitHub or reach out on Twitter.

BetterStarter uses Better Auth with emailOTP. Users enter their email, receive a 6-digit code, and sign in — no passwords needed.

1. Set Up Plunk (Email Provider)

  1. Create a free account at useplunk.com
  2. Verify your sending domain in the Plunk dashboard
  3. Copy your Secret API key

2. Set Environment Variables

# .env.local
PLUNK_SECRET_API_KEY=your_plunk_secret_api_key
TRANSACTIONAL_EMAIL=noreply@yourdomain.com

3. Test

  1. Run pnpm dev
  2. Navigate to /auth/sign-in
  3. Enter an email and request a code
  4. In development, the OTP is also logged to the server console
  5. Enter the 6-digit code to sign in

Configuration

OTP settings are in src/constants/auth.ts:

export const OTP_CONFIG = {
  LENGTH: 6,
  EXPIRES_IN_SECONDS: 300, // 5 minutes
}

Swapping Email Providers

To use Resend, SendGrid, or another service, update the sendOTPEmail function in src/lib/auth/index.ts. It receives the recipient email and the OTP code.

Troubleshooting

  • No email received — check server console for the OTP (logged in dev). In production, verify your Plunk API key and sending domain.
  • Code expired — adjust EXPIRES_IN_SECONDS in src/constants/auth.ts
  • Spam folder — configure SPF, DKIM, and DMARC for your sending domain

On this page