Why Better-Auth is dominating TypeScript authentication in 2026
Better-Auth has rapidly emerged as the primary authentication library for modern TypeScript stacks. Unlike legacy authentication libraries that tightly couple to monolithic database ORMs or enforce complex multi-file configurations, Better-Auth is lightweight, framework-agnostic, and built with first-class plugin support.
However, an authentication library only handles session state and token generation. The critical moment in user onboarding — delivering the verification link or 6-digit one-time password (OTP) — depends entirely on your transactional email infrastructure. If verification emails take 45 seconds to arrive or get flagged as spam by Google and Microsoft, users abandon signup.
By pairing Better-Auth with SadaSend, you get sub-150ms ingestion latency, native Dual-DKIM signing (RSA-2048 + Ed25519), and an in-flight bounce shield that detects dead or misspelled mailboxes before they pollute your user database.
| Auth Feature | Better-Auth Mechanism | SadaSend Delivery Advantage |
|---|---|---|
| Email Verification | requireEmailVerification: true | Sub-150ms direct MX dispatch with zero waiting in queue |
| Password Resets | sendResetPassword hook | Authenticated TLS submission on dedicated EU infrastructure |
| Magic Link Login | magicLink plugin | In-flight link scanning ensures clean spam reputation |
| Two-Factor OTP | twoFactor / emailOTP plugin | Instant delivery before the 5-minute code window expires |
1. Installing dependencies & configuring the SadaSend client
First, install Better-Auth and the official SadaSend TypeScript SDK in your project:
npm install better-auth sadasendNext, create your centralized authentication configuration in lib/auth.ts. We initialize the SadaSend client using your scoped API key:
2. Wiring sendVerificationEmail & sendResetPassword in auth.ts
Better-Auth provides clean async callbacks for outbound transactional emails. Here is the complete production configuration with pre-send bounce defense enabled:
import { betterAuth } from 'better-auth';
import { SadaSend } from 'sadasend';
// Initialize SadaSend with scoped API credentials
const sadasend = new SadaSend({
apiKey: process.env.SADASEND_API_KEY!,
});
export const auth = betterAuth({
emailAndPassword: {
enabled: true,
requireEmailVerification: true,
sendVerificationEmail: async ({ user, url }) => {
// Dispatch verification link with in-flight bounce defense
const response = await sadasend.emails.send({
from: 'security@yourdomain.com',
to: user.email,
subject: 'Verify your email address',
html: `
<div style="font-family: sans-serif; max-width: 560px; margin: 0 auto;">
<h2>Verify your account</h2>
<p>Hi ${user.name || 'there'},</p>
<p>Click the link below to verify your email and activate your account:</p>
<p><a href="${url}" style="display: inline-block; padding: 12px 24px; background: #000; color: #fff; text-decoration: none; border-radius: 6px;">Verify Email</a></p>
<p style="color: #666; font-size: 13px;">If you did not request this, please ignore this email.</p>
</div>
`,
verifyBeforeSend: true, // Blocks invalid syntax & dead MX domains
});
console.log('Verification dispatched:', response.id);
},
sendResetPassword: async ({ user, url }) => {
await sadasend.emails.send({
from: 'security@yourdomain.com',
to: user.email,
subject: 'Reset your password',
html: `
<div style="font-family: sans-serif; max-width: 560px; margin: 0 auto;">
<h2>Password Reset Request</h2>
<p>Click below to reset your password. This link expires in 15 minutes:</p>
<p><a href="${url}" style="display: inline-block; padding: 12px 24px; background: #000; color: #fff; text-decoration: none; border-radius: 6px;">Reset Password</a></p>
</div>
`,
});
},
},
});3. Supporting Email OTP and 2FA with Better-Auth plugins
If your application relies on 6-digit numeric OTP verification codes rather than clickable magic links, Better-Auth’s emailOTP plugin connects seamlessly using the same SadaSend client:
import { emailOTP } from 'better-auth/plugins';
export const auth = betterAuth({
plugins: [
emailOTP({
async sendVerificationOTP({ email, otp, type }) {
await sadasend.emails.send({
from: 'auth@yourdomain.com',
to: email,
subject: `Your ${type === 'sign-in' ? 'Login' : 'Verification'} Code: ${otp}`,
html: `
<div style="font-family: sans-serif; text-align: center; padding: 24px;">
<h2>Your Verification Code</h2>
<p style="font-size: 32px; font-weight: bold; letter-spacing: 4px; color: #111;">${otp}</p>
<p style="color: #666;">This code is valid for 5 minutes. Do not share it with anyone.</p>
</div>
`,
tags: ['auth-otp', type],
});
},
}),
],
});4. Testing auth flows in CI/CD without polluting real inboxes
In automated test suites (e.g. Playwright or Cypress), testing Better-Auth email verification usually requires fragile third-party mail tools. SadaSend includes native ephemeral test inboxes with real-time Server-Sent Events push streams, allowing your CI pipeline to extract the verification link and click it in under 150ms without waiting for polling loops.
Frequently Asked Questions
Building AI agents that send email?
Scoped API keys, per-key recipient allowlists, approval mode and a hosted MCP server with twelve tools — 6,000 free sends monthly, without a credit card.
Building SadaSend — transactional email with an MCP server that has a ceiling. Writes about deliverability, email infrastructure, and what happens when you hand an autonomous agent a sending credential.