An open API service indexing awesome lists of open source software.

https://github.com/delmaredigital/payload-better-auth

Better Auth adapter and plugins for Payload CMS
https://github.com/delmaredigital/payload-better-auth

authentication better-auth nextjs payload-plugin payloadcms plugin typescript

Last synced: 26 days ago
JSON representation

Better Auth adapter and plugins for Payload CMS

Awesome Lists containing this project

README

          

# @delmaredigital/payload-better-auth

Better Auth adapter and plugins for Payload CMS. Enables seamless integration between Better Auth and Payload.


Live Demo - Try It Now
  
Starter Template - Use This


Deploy with Vercel

> ⚠️ **Upgrading to 0.7?** This release requires **Better Auth 1.6** and includes several breaking changes:
>
> - **Schema migration required** for projects using the `twoFactor` plugin — Better Auth 1.6.2 added a `verified` column to the `twoFactor` table.
> - **`oidcProvider` → `@better-auth/oauth-provider`** — generated OAuth types now reflect the `oauth-provider` schema. Consumers using `oidcProvider()` at runtime will keep working, but `OauthApplication` / `PluginId` / `ModelKey` type exports have changed shape. Migrating to `@better-auth/oauth-provider` is recommended.
> - **Client helper type widening** — `createPayloadAuthClient()` and `payloadAuthPlugins` are typed more conservatively to keep `.d.ts` portable. For typed plugin methods (e.g. `client.twoFactor.verifyTotp`), list plugins explicitly in `createAuthClient({ plugins: [...] })` (see [Client-Side Auth](#4-client-side-auth) below).
>
> See the [CHANGELOG](./CHANGELOG.md#070---2026-04-21) for full migration instructions.

---

## Documentation

**[Full Documentation](https://delmaredigital.github.io/payload-better-auth/)** — API reference, guides, recipes, UI components, and more.

For AI-assisted exploration: [DeepWiki](https://deepwiki.com/delmaredigital/payload-better-auth)

---

## Install

```bash
pnpm add @delmaredigital/payload-better-auth better-auth
```

**Requirements:** `payload` >= 3.69.0 · `better-auth` >= 1.6.0 · `next` >= 15.4.8 · `react` >= 19.2.1

## Quick Start

### 1. Auth Configuration

```ts
// src/lib/auth/config.ts
import type { BetterAuthOptions } from 'better-auth'

export const betterAuthOptions: Partial = {
user: {
additionalFields: {
role: { type: 'string', defaultValue: 'user' },
},
},
emailAndPassword: { enabled: true },
}
```

### 2. Users Collection

```ts
// src/collections/Users/index.ts
import type { CollectionConfig } from 'payload'
import { betterAuthStrategy } from '@delmaredigital/payload-better-auth'

export const Users: CollectionConfig = {
slug: 'users',
auth: {
disableLocalStrategy: true,
strategies: [betterAuthStrategy()],
},
access: {
read: ({ req }) => {
if (!req.user) return false
if (req.user.role === 'admin') return true
return { id: { equals: req.user.id } }
},
admin: ({ req }) => req.user?.role === 'admin',
},
fields: [
{ name: 'email', type: 'email', required: true, unique: true },
{ name: 'emailVerified', type: 'checkbox', defaultValue: false },
{ name: 'name', type: 'text' },
{ name: 'image', type: 'text' },
{
name: 'role',
type: 'select',
defaultValue: 'user',
options: [
{ label: 'User', value: 'user' },
{ label: 'Admin', value: 'admin' },
],
},
],
}
```

### 3. Payload Config

```ts
// src/payload.config.ts
import { buildConfig } from 'payload'
import { postgresAdapter } from '@payloadcms/db-postgres'
import { betterAuth } from 'better-auth'
import {
betterAuthCollections,
createBetterAuthPlugin,
payloadAdapter,
} from '@delmaredigital/payload-better-auth'
import { betterAuthOptions } from './lib/auth/config'
import { Users } from './collections/Users'
import { getBaseUrl } from './lib/auth/getBaseUrl'

const baseUrl = getBaseUrl()

export default buildConfig({
collections: [Users],
plugins: [
betterAuthCollections({
betterAuthOptions,
skipCollections: ['user'],
}),
createBetterAuthPlugin({
createAuth: (payload) =>
betterAuth({
...betterAuthOptions,
database: payloadAdapter({ payloadClient: payload }),
advanced: { database: { generateId: 'serial' } },
baseURL: baseUrl,
secret: process.env.BETTER_AUTH_SECRET,
trustedOrigins: [baseUrl],
}),
}),
],
db: postgresAdapter({
pool: { connectionString: process.env.DATABASE_URL },
}),
})
```

### 4. Client-Side Auth

```ts
// src/lib/auth/client.ts
'use client'

import { createAuthClient, twoFactorClient } from '@delmaredigital/payload-better-auth/client'
import { passkeyClient } from '@better-auth/passkey/client'

export const authClient = createAuthClient({
plugins: [twoFactorClient(), passkeyClient()],
})

export const { useSession, signIn, signUp, signOut, twoFactor, passkey } = authClient
```

> Listing plugins inline (rather than using `createPayloadAuthClient()` or spreading `payloadAuthPlugins`) ensures `twoFactor` and other plugin methods are typed on the returned client.

### 5. Server-Side Session

```ts
import { headers } from 'next/headers'
import { getPayload } from 'payload'
import { getServerSession } from '@delmaredigital/payload-better-auth'

export default async function Dashboard() {
const payload = await getPayload({ config })
const headersList = await headers()
const session = await getServerSession(payload, headersList)

if (!session) { redirect('/login') }

return

Hello {session.user.name}

}
```

**That's it!** The plugin automatically registers auth API endpoints at `/api/auth/*`, injects admin UI components, and handles session management.

---

For MongoDB setup, API reference, customization, access control helpers, API key scopes, plugin compatibility, UI components (2FA, passkeys, password reset), recipes, and types — see the **[full documentation](https://delmaredigital.github.io/payload-better-auth/)**.

## License

MIT