Community adapters for Better Auth
Better Auth connects to databases through adapters. Beyond the official adapters maintained by the Better Auth team, the community has built many additional adapters to support other databases. Community members are encouraged to create custom adapters and can submit pull requests to have them added to the community adapters list.
How to create a custom database adapter
To create a custom database adapter for Better Auth, start by reading the Create a Database Adapter guide. If you want to share your adapter with the community, open a pull request to add it to the community adapters list.
Enable joins in MongoDB adapter
To enable the experimental joins feature in Better Auth, pass experimental: { joins: true } in the betterAuth configuration object.
MongoDB adapter package installation
To use the MongoDB adapter, install the @better-auth/mongo-adapter package.
MongoDB adapter initialization with client
The mongodbAdapter function is imported from better-auth/adapters/mongodb and accepts a database connection and an optional configuration object. The configuration object can include a client property. If a client is not provided, database transactions will not be enabled.
MongoDB schema generation and migration
MongoDB does not require schema generation or migration when using the Better Auth MongoDB adapter.
MongoDB adapter joins support
The MongoDB adapter supports database joins starting from version 1.4.0. Joins enable Better Auth to fetch related data from multiple collections in a single query, providing 2x to 3x performance improvements depending on database latency. To enable joins, set the experimental.joins option to true in the auth configuration.
Schema generation with Better Auth CLI for Drizzle
Use 'npx auth@latest generate' to generate the schema required by Better Auth based on your configuration and plugins.
Drizzle migration with drizzle-kit
Run 'npx drizzle-kit generate' to generate a migration file, then 'npx drizzle-kit migrate' to apply the migration to your database.
Drizzle adapter joins experimental feature
The Drizzle adapter supports joins since version 1.4.0 to fetch related data from multiple tables in a single query, providing 2x to 3x performance improvements. Enable it by setting experimental.joins to true in the auth configuration.
Drizzle adapter joins requirement for relations
To use the joins feature, your Drizzle schema must have the necessary relations defined. You can use the drizzle-orm relation function or regenerate the schema with 'npx auth@latest generate' to automatically include relations.
Drizzle adapter relationName requirement for multiple foreign keys
When a table has multiple foreign keys to the same table, each relation pair must use a matching relationName. The CLI generates these names automatically following your table naming: with usePlural: true it is plural (tests_userId), otherwise singular (test_userId). Both sides of the relation must have identical relationName values.
Drizzle adapter relationName pitfall with singular and plural
Do not keep both singular and plural aliases for the same foreign key (for example, both user and users). Drizzle treats those as separate relations and cannot infer which reverse relation a join should use.
Drizzle adapter custom table name mapping
The Drizzle adapter expects schema table names to match Better Auth table names. If your Drizzle schema maps the user table to users, you can manually pass the schema object and map it using drizzleAdapter(db, { provider: "sqlite", schema: { ...schema, user: schema.users } }).
Drizzle adapter modelName configuration option
You can modify the table name by setting the modelName property in the auth configuration, for example user: { modelName: "users" }, instead of passing a custom schema object.
Drizzle adapter custom field name mapping
Field names are mapped based on the property name in the Drizzle schema. To use a different database column name, modify the Drizzle schema definition, for example email: varchar("email_address", { length: 255 }).notNull().unique(), while keeping the property name as email.
Drizzle adapter fields configuration option
You can map custom field names by setting the fields property in the auth configuration, for example user: { fields: { email: "email_address" } }, instead of modifying the Drizzle schema directly.
Drizzle adapter usePlural option
The usePlural option in drizzleAdapter configuration allows you to use plural table names for all tables. Set it to true if all your tables follow a plural naming convention.
Drizzle adapter package installation
Install the @better-auth/drizzle-adapter package to use Drizzle ORM as a database adapter for Better Auth.
Drizzle adapter configuration with provider option
The drizzleAdapter function takes a database instance and a configuration object. The provider option specifies the database type and accepts values: "sqlite", "pg" (PostgreSQL), or "mysql".
Drizzle adapter basic usage example
To configure Better Auth with Drizzle, import betterAuth and drizzleAdapter, then pass drizzleAdapter(db, { provider: "sqlite" }) to the database option in the auth configuration.
MySQL adapter implementation via Kysely
MySQL is supported in Better Auth through the Kysely adapter. Any database supported by Kysely is also supported by Better Auth.
MySQL adapter database option - createPool example
To configure a MySQL database in Better Auth, use the database option with mysql2/promise's createPool function. The createPool call takes host, user, password, database, and timezone parameters. Example: createPool({ host: "localhost", user: "root", password: "password", database: "database", timezone: "Z" }). The timezone parameter is important to ensure consistent timezone values.
MySQL CLIENT_FOUND_ROWS flag requirement
The Kysely adapter for MySQL relies on the MySQL driver reporting "rows matched" semantics for UPDATE operations. The mysql2 driver enables the CLIENT_FOUND_ROWS client flag by default, which must remain on. If you disable it by passing flags: '-FOUND_ROWS' to createPool, MySQL falls back to "rows changed" semantics. This causes idempotent UPDATE operations (where the new value equals the current value) to report zero affected rows, making adapter.update, incrementOne, and updateMany treat the operation as a miss even though the predicate matched.
MySQL schema generation and migration support
MySQL supports both schema generation and migration through the Better Auth CLI using the commands npx auth@latest generate and npx auth@latest migrate respectively.
MySQL experimental joins feature
Database joins is an experimental feature that allows Better Auth to fetch related data from multiple tables in a single query, providing 2x to 3x performance improvements depending on database latency. To enable this feature, set the experimental.joins option to true in the auth configuration. The Kysely MySQL dialect supports joins out of the box since version 1.4.0. You may need to run migrations after enabling this feature.
Complete MS SQL adapter example with betterAuth setup
import { betterAuth } from "better-auth";
import { MssqlDialect } from "kysely";
import * as Tedious from 'tedious'
import * as Tarn from 'tarn'
const dialect = new MssqlDialect({
tarn: {
...Tarn,
options: {
min: 0,
max: 10,
},
},
tedious: {
...Tedious,
connectionFactory: () => new Tedious.Connection({
authentication: {
options: {
password: 'password',
userName: 'username',
},
type: 'default',
},
options: {
database: 'some_db',
port: 1433,
trustServerCertificate: true,
},
server: 'localhost',
}),
},
TYPES: {
...Tedious.TYPES,
DateTime: Tedious.TYPES.DateTime2,
},
})
export const auth = betterAuth({
database: {
dialect,
type: "mssql"
}
});
MS SQL database adapter setup with Kysely MssqlDialect
To configure MS SQL with Better Auth, import betterAuth from 'better-auth', create an MssqlDialect instance with Tedious connection factory and Tarn pool configuration, then pass it to betterAuth with database.type set to 'mssql'. The MssqlDialect requires tarn pool options (min and max), tedious connection configuration with authentication, server details, and port 1433, and TYPES mapping that sets DateTime to DateTime2.
MS SQL experimental joins feature
The Kysely MS SQL dialect supports joins since version 1.4.0. To enable joins in Better Auth, set experimental.joins to true in the auth configuration. This feature can provide 2x to 3x performance improvements for endpoints like /get-session and /get-full-organization. Migrations may be required after enabling this feature.
MS SQL MssqlDialect Tarn pool configuration
The Tarn pool configuration for MS SQL requires min and max options. The example uses min: 0 and max: 10 for connection pooling.
MS SQL Tedious connection configuration
Tedious connection for MS SQL requires: authentication with type 'default' and options containing password and userName; options object with database name, port (default 1433), and trustServerCertificate boolean; and server hostname. The TYPES object must include DateTime mapped to Tedious.TYPES.DateTime2.
Better Auth database dialect support via Kysely
Better Auth supports a wide range of database dialects out of the box thanks to Kysely. Any dialect supported by Kysely can be utilized with Better Auth, including capabilities for generating and migrating database schemas through the CLI.
Core database dialects supported by Better Auth
Better Auth has core support for these database dialects: MySQL, SQLite, PostgreSQL, and MS SQL.
Kysely Organization dialects for Better Auth
Better Auth can use these dialects provided by the Kysely organization: Postgres.js, SingleStore Data API, and Supabase.
Kysely Community dialects for Better Auth
Better Auth can use these community-provided Kysely dialects: PlanetScale Serverless Driver, Cloudflare D1, AWS RDS Data API, Prisma Postgres, SurrealDB, Neon, Xata, AWS S3 Select, libSQL/sqld, Fetch driver, SQLite WASM, Deno SQLite, TiDB Cloud Serverless Driver, Capacitor SQLite Kysely, BigQuery, Clickhouse, and PGLite.
Prisma adapter package installation
To use the Prisma adapter with Better Auth, install the @better-auth/prisma-adapter package.
Prisma adapter joins feature
The Prisma adapter supports database joins starting from version 1.4.0, which can provide 2x to 3x performance improvements depending on database latency. Joins are enabled by setting experimental.joins to true in the auth configuration. The Prisma schema must have necessary relations defined using the @relation directive or generated via npx auth@latest generate.
Prisma adapter usage example
The Prisma adapter is configured by importing PrismaClient from @prisma/client, creating an instance, and passing it to betterAuth with prismaAdapter(prisma, { provider: "sqlite" }).
Prisma schema generation support
The Better Auth CLI supports Prisma schema generation via npx auth@latest generate, but Prisma schema migration is not supported.
Prisma 7 output path configuration
Starting from Prisma 7, the output path field is required in the schema.prisma file. If a custom output path is configured (e.g., output = "../src/generated/prisma"), the Prisma client must be imported from that location instead of @prisma/client.
PostgreSQL non-default schema configuration option 2
To use a non-default PostgreSQL schema, set the search_path using Pool options. Pass options property with value '-c search_path=auth' to the Pool constructor along with other connection parameters like host, port, user, password, and database.
PostgreSQL non-default schema configuration option 3
To use a non-default PostgreSQL schema, set the PostgreSQL user's default schema using: ALTER USER your_user SET search_path TO auth;. Reconnect to apply the changes.
PostgreSQL non-default schema prerequisites
Before using a non-default schema, ensure the schema exists by running: CREATE SCHEMA IF NOT EXISTS auth;. Then grant appropriate permissions: GRANT ALL PRIVILEGES ON SCHEMA auth TO your_user; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA auth TO your_user; ALTER DEFAULT PRIVILEGES IN SCHEMA auth GRANT ALL ON TABLES TO your_user;
Better Auth CLI detects configured PostgreSQL schema
When running 'npx auth migrate', the Better Auth CLI automatically detects and inspects only tables in the configured search_path schema. Tables in other schemas are ignored to prevent conflicts, and all new tables are created in the specified schema.
PostgreSQL schema troubleshooting
If encountering 'relation does not exist' error during migration, this usually means the schema doesn't exist or the user lacks permissions. Create the schema and grant permissions as documented. Verify the schema configuration by running: SHOW search_path; which should return the custom schema as the first value.
PostgreSQL supported via Kysely adapter
PostgreSQL is supported in Better Auth through the Kysely adapter. Any database supported by Kysely would also be supported by Better Auth.
PostgreSQL schema generation and migration support
PostgreSQL supports both schema generation and schema migration using the Better Auth CLI. Use 'npx auth@latest generate' for schema generation or 'npx auth@latest migrate' for schema migration.
Enable experimental joins for PostgreSQL
The Kysely PostgreSQL dialect supports joins starting from version 1.4.0. To enable this feature for better query performance, set experimental.joins to true in the auth configuration. This can provide 2x to 3x performance improvements depending on database latency. Running migrations after enabling this feature may be necessary.
PostgreSQL non-default schema configuration option 1
To use a non-default PostgreSQL schema (e.g., 'auth' instead of 'public'), append the options parameter to the connection URI. Example: 'postgres://user:password@localhost:5432/database?options=-c search_path=auth'. URL-encode if needed: '?options=-c%20search_path%3Dauth'.
SQLite driver options in Better Auth
Better Auth supports three SQLite drivers: Better-SQLite3 (recommended), Node.js built-in SQLite, and Bun built-in SQLite. Better-SQLite3 is the most popular and stable SQLite driver for Node.js. Node.js built-in SQLite requires Node.js 22.5.0 or later and no longer requires the --experimental-sqlite flag since Node.js 22.13.0 / 23.4.0. Bun's built-in SQLite is similar to the Node.js version.
SQLite support via Kysely adapter
SQLite in Better Auth is supported under the hood via the Kysely adapter. Any database supported by Kysely is also supported by Better Auth.
Experimental joins feature for SQLite
Database joins in SQLite can provide 2x to 3x performance improvements depending on database latency by allowing Better Auth to fetch related data from multiple tables in a single query. The Kysely SQLite dialect supports joins out of the box since version 1.4.0. Enable this feature by setting experimental.joins to true in the auth configuration. It is possible that migrations may need to be run after enabling this feature.
SQLite schema generation and migration support
SQLite with Better Auth supports both schema generation and schema migration via the Better Auth CLI. Use 'npx auth@latest generate' for schema generation and 'npx auth@latest migrate' for schema migration.
Node.js built-in SQLite configuration
To use Node.js built-in SQLite with Better Auth, import betterAuth from better-auth and DatabaseSync from node:sqlite, then pass a DatabaseSync instance to the database option: new DatabaseSync('database.sqlite'). Run the application with 'node your-app.js'.
Bun built-in SQLite configuration
To use Bun's built-in SQLite with Better Auth, import betterAuth from better-auth and Database from bun:sqlite, then pass a Database instance to the database option: new Database('database.sqlite'). When running CLI commands, use bunx with the --bun flag to prevent type errors, for example: bunx --bun auth@latest generate.
Database connection setup for migration using PostgreSQL
To connect to a PostgreSQL database for migration, install pg with `npm install pg`, then configure Better Auth with the database option using `new Pool({ connectionString: process.env.DATABASE_URL })`.
Adapter createSchema method - optional
The createSchema method (optional) allows the Better Auth CLI to generate a schema for the database. Parameters: tables (array of table definitions from user's Better-Auth instance schema to be generated into schema file), file (string, the file path user may have passed to the generate command as expected schema output location).
createAdapterFactory function overview
The createAdapterFactory function is the main tool for creating custom database adapters for Better Auth. It handles custom schema configurations, custom ID generation, safe JSON parsing, key mapping, joins, and more, allowing developers to focus on writing database logic without managing adapter-framework interactions.
Custom adapter config interface structure
Custom adapters should define a CustomAdapterConfig interface representing adapter-specific configuration options. The interface is passed to the adapter factory function and can include options like debugLogs (DBAdapterDebugLogOption type) and usePlural (boolean). The adapter factory function is then created by calling createAdapterFactory with this config.
Adapter factory config object - required fields
The config object passed to createAdapterFactory must include: adapterId (string, unique identifier for the adapter) and adapterName (string, name of the adapter).