• Start

Authentication

/

Better Auth

Getting started

Install the @surrealdb/better-auth adapter, connect to SurrealDB, configure the adapter, and generate your Better Auth schema.

This guide walks through installing the @surrealdb/better-auth adapter, connecting it to SurrealDB, and generating the schema Better Auth needs.

Install the adapter alongside better-auth and the SurrealDB JavaScript SDK:

bun add @surrealdb/better-auth better-auth surrealdb

Connect a Surreal client, then pass it to surrealAdapter as the database option in your Better Auth configuration. Better Auth manages all table operations through the adapter.

import { betterAuth } from 'better-auth';
import { Surreal } from 'surrealdb';
import { surrealAdapter } from '@surrealdb/better-auth';

const db = new Surreal();
await db.connect('ws://localhost:8000/rpc');
await db.use({ namespace: 'namespace', database: 'database' });

export const auth = betterAuth({
database: surrealAdapter({ db }),
emailAndPassword: { enabled: true },
});

The adapter accepts any connected Surreal instance. Connect it before passing it to surrealAdapter. Use WebSocket for long-running servers and HTTP for stateless environments such as serverless functions.

import { Surreal } from 'surrealdb';

const db = new Surreal();

// WebSocket (recommended for persistent servers)
await db.connect('ws://localhost:8000/rpc', {
namespace: 'myapp',
database: 'production',
authentication: {
username: 'root',
password: 'root',
},
});

// HTTP (for stateless environments)
await db.connect('http://localhost:8000', {
namespace: 'myapp',
database: 'production',
});

For a full reference of connection options, see Connecting to SurrealDB in the JavaScript SDK documentation.

surrealAdapter accepts the following options:

OptionTypeDefaultDescription
dbSurrealrequiredA connected SurrealDB client instance.
usePluralbooleanfalseUse plural table names (users instead of user).
schemaMode'schemafull' \| 'schemaless''schemafull'Table mode used by the generated schema. schemaless keeps known fields typed and indexed while still accepting writes to undeclared fields.
surrealAdapter({
db,
usePlural: true, // use plural table names
});

The adapter includes a createSchema implementation that generates SurrealQL DDL statements for all Better Auth tables. Use the Better Auth CLI to produce a schema.surql file:

bunx @better-auth/cli generate --output schema.surql

Then apply it to your SurrealDB instance:

surreal import --conn http://localhost:8000 \
--ns myapp --db production \
--user root --pass root \
schema.surql

The generated schema uses SCHEMAFULL tables by default. Each field is typed from the Better Auth schema:

  • Required fields take a concrete type (string, datetime, bool, and so on).

  • Optional fields use option<T | null>, so they accept a typed value, a stored NULL, or a missing value.

  • Object fields are marked FLEXIBLE so they can hold arbitrary keys.

  • DEFINE INDEX statements are emitted for unique fields and for fields Better Auth marks as indexed.

Every statement uses IF NOT EXISTS, so the file is safe to reapply.

By default the adapter uses singular table names: user, session, verification, and account. Set usePlural: true to use plural names instead.

Better Auth also lets you override model names per-table via the modelName option in your configuration, and the adapter respects those overrides automatically.

  • Overview: adapter capabilities and prerequisites

  • Plugins: use any Better Auth plugin and the SurrealQL helper functions generated for the organisation plugin.

  • Transactions & limitations: how transactions behave and what to be aware of.

Was this page helpful?