Better Auth Integration
Block disposable emails at the auth layer using Better Auth's databaseHooks. Users with throwaway emails are rejected before they ever reach your database.
What is Better Auth?
Better Auth is a modern authentication library for TypeScript. If you use it for signups, this integration blocks disposable emails automatically.
Using databaseHooks
The databaseHooks.user.create.before hook runs before a user is inserted into the database. Return false to reject the signup.
lib/auth.tstypescript
import { betterAuth } from 'better-auth';
import { isDisposable } from '@isdisposable/js';
export const auth = betterAuth({
// ... your config
databaseHooks: {
user: {
create: {
before: async (user) => {
if (isDisposable(user.email)) {
return false; // Block signup
}
return user; // Allow signup
},
},
},
},
});Instant, offline
This uses the free package — no API key needed, no network calls. The check happens in under 1ms.
With Pro API (risk scoring)
For stricter protection with real-time DNS checks and risk scoring:
lib/auth.tstypescript
import { betterAuth } from 'better-auth';
import { createIsDisposable } from '@isdisposable/js';
const checker = createIsDisposable({
apiKey: process.env.ISDISPOSABLE_API_KEY!,
});
export const auth = betterAuth({
// ... your config
databaseHooks: {
user: {
create: {
before: async (user) => {
const result = await checker.check(user.email);
// Block if score is 70 or higher
if (result.score >= 70) {
return false;
}
return user;
},
},
},
},
});Tune your threshold
score ≥ 50 — blocks most disposable emails (default).
score ≥ 70 — stricter, fewer false positives.
score ≥ 90 — only blocks emails confirmed in the blocklist.
score ≥ 70 — stricter, fewer false positives.
score ≥ 90 — only blocks emails confirmed in the blocklist.
Custom error messages
To show a helpful error message on the client side, throw an APIError:
lib/auth.tstypescript
import { betterAuth } from 'better-auth';
import { APIError } from 'better-auth/api';
import { isDisposable } from '@isdisposable/js';
export const auth = betterAuth({
databaseHooks: {
user: {
create: {
before: async (user) => {
if (isDisposable(user.email)) {
throw new APIError('BAD_REQUEST', {
message: 'Please use a permanent email address. Disposable emails are not allowed.',
});
}
return user;
},
},
},
},
});Log-only mode
Want to monitor without blocking? Log disposable signups instead:
lib/auth.tstypescript
databaseHooks: {
user: {
create: {
before: async (user) => {
if (isDisposable(user.email)) {
console.warn(`[isDisposable] Suspicious signup: ${user.email.split('@')[1]}`);
// Allow the signup but flag it
}
return user;
},
},
},
}This logs the domain only (not the full email) for privacy. You can review the logs and decide whether to start blocking.