Adding Better Auth Plugins

How to add and configure new Better Auth plugins

This guide explains how to add new Better Auth plugins to your application.

Examples below use placeholder names like <your-plugin>. Replace these with the actual plugin name from Better Auth's plugin documentation.

Plugin Location

Plugins are configured in:

packages/better-auth/
└── src/
├── auth.ts # Server-side auth instance
├── auth-client.ts # Client-side auth instance
└── plugins/
├── index.ts # Plugin registry
└── *.ts # Individual plugin configs

Step 1: Create Plugin File

Create a new file in packages/better-auth/src/plugins/:

// <your-plugin>.ts
import { yourPlugin } from 'better-auth/plugins/<your-plugin>';
/**
* @name yourPluginConfig
* @description What this plugin does
*/
export const yourPluginConfig = yourPlugin({
// plugin options from Better Auth docs
});

Plugin Patterns

Simple plugin - direct export when no dynamic config needed:

// Example: adding the Bearer plugin
import { bearer } from 'better-auth/plugins/bearer';
export const bearerPlugin = bearer();

Factory function - when plugin needs runtime environment values:

// Example: plugin that needs env config
import { yourPlugin } from 'better-auth/plugins/<your-plugin>';
import { env } from '@kit/shared/env';
export function createYourPlugin() {
return yourPlugin({
issuer: env('NEXT_PUBLIC_PRODUCT_NAME'),
});
}

Conditional plugin - when plugin depends on optional env vars:

// Example: plugin enabled only when secret is configured
import * as z from 'zod';
const secretKey = z.string().min(1).optional().parse(process.env.YOUR_PLUGIN_SECRET);
export async function createYourPlugin() {
if (!secretKey) {
return [] as never;
}
const { yourPlugin } = await import('better-auth/plugins/<your-plugin>');
return [yourPlugin({ secretKey })];
}

Step 2: Register Server Plugin

Add your plugin to packages/better-auth/src/plugins/index.ts:

import { yourPluginConfig } from './<your-plugin>';
// or for factory pattern:
import { createYourPlugin } from './<your-plugin>';
export const betterAuthPlugins = [
// ... existing plugins
// Simple plugin
yourPluginConfig,
// Factory plugin
createYourPlugin(),
// Conditional plugin (spread array)
...(await createYourPlugin()),
];

Step 3: Register Client Plugin

If the plugin has client-side functionality, add it to packages/better-auth/src/auth-client.ts:

import { yourPluginClient } from 'better-auth/client/plugins';
export const authClient = createAuthClient({
plugins: [
// ... existing plugins
yourPluginClient(),
],
});

Step 4: Database Schema

If the plugin adds database tables:

  1. Generate the Better Auth schema:
pnpm --filter @kit/better-auth schema:generate
  1. Generate Drizzle migrations:
pnpm --filter @kit/database drizzle-kit generate
  1. Apply migrations:
pnpm --filter @kit/database drizzle-kit migrate

Step 5: Environment Variables

If your plugin requires secrets or configuration:

  1. Add variables to .env.local:
YOUR_PLUGIN_SECRET=your-secret-value
NEXT_PUBLIC_YOUR_PLUGIN_KEY=public-value
  1. Validate with Zod in your plugin file:
import * as z from 'zod';
const pluginSecret = z
.string({ error: 'YOUR_PLUGIN_SECRET is required' })
.min(32, 'Secret must be at least 32 characters')
.parse(process.env.YOUR_PLUGIN_SECRET);

Email Handlers

Plugins that send emails should use dynamic imports:

export const yourPluginConfig = yourPlugin({
sendEmail: async ({ user, url }) => {
const { sendYourPluginEmail } =
await import('../emails/send-your-plugin-email');
await sendYourPluginEmail({
email: user.email,
url,
productName: getProductName(),
});
},
});

Real-World Example: Adding the Bearer Plugin

This example shows adding the Bearer plugin for API token authentication:

// packages/better-auth/src/plugins/bearer.ts
import { bearer } from 'better-auth/plugins/bearer';
/**
* @name bearerPlugin
* @description Enables Bearer token authentication for API routes
*/
export const bearerPlugin = bearer();

Then register in plugins/index.ts:

import { bearerPlugin } from './bearer';
export const betterAuthPlugins = [
// ... existing plugins
bearerPlugin,
];

And add the client plugin in auth-client.ts:

import { bearerClient } from 'better-auth/client/plugins';
export const authClient = createAuthClient({
plugins: [
// ... existing plugins
bearerClient(),
],
});

Next: Auth Methods →