Overview
Email sign-in is fully wired with Better Auth and Resend. Users enter their email, receive a 6-digit one-time password (OTP), and verify it in-app to create a session. Resend is the email delivery service used by the boilerplate to send OTP codes. OTP is a short, time-limited code that lets users sign in without a password. The API generates the code, sends it via Resend, and verifies it when the user enters it on mobile.Prerequisites
- A Resend account
- A Resend API key
- Backend environment configured
How OTP works
- The user enters their email in the app.
- The API generates an OTP and sends it via Resend.
- The user enters the OTP, and the API verifies it.
- Better Auth creates the session and the app becomes authenticated.
Where it is configured
The boilerplate already includes the email OTP wiring:- Backend auth service and Resend send logic:
apps/api/src/services/auth.ts - Better Auth request handling:
apps/api/src/routes/auth/auth.ts - Mobile screens for email input and OTP verification:
apps/mobile/app/auth/email-signin.tsx,apps/mobile/app/auth/verify-email-otp.tsx - Session handling on mobile:
apps/mobile/lib/auth/session-context.tsx
Setup steps
Step 1: Create a Resend API key
Sign in to Resend, then create an API key from the API Keys page.Step 2: Add the API key to your backend env
Copyapps/api/example.env to apps/api/.env if you have not already, then set
RESEND_API_KEY to your Resend API key.
Restart the API after updating backend environment values.
Step 3: Verify your sending domain (production)
For production email delivery, verify your domain in Resend Domains and follow their DNS instructions. The sender address is defined inapps/api/src/services/auth.ts. Update it to
use an address on your verified domain.
Step 4: Test email sign-in
Open the app, enter an email address, and request a code. You should receive an OTP email and be able to complete the sign-in flow.Notes
- If you are not receiving emails in development, confirm your Resend API key and check spam folders.
- If OTP verification fails, confirm the API is running and reachable from the device, and restart it after env changes.