Better Auth ConsoleBetter Auth Console

Configuration

Configure Better Auth Console to connect to your better-auth databases.

All configuration happens in a single file: instances.config.ts at the project root.

Overview

The console connects to your existing better-auth databases using the same adapters and plugins you already have configured. You just need to:

  1. Create database connections
  2. Configure better-auth instances
  3. Export them as an array

Basic Structure

instances.config.ts
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import * as schema from "./apps/web/lib/schema";

// Database connection
const client = postgres(process.env.DATABASE_URL!);
const db = drizzle(client, { schema });

// Better-auth instance
const auth = betterAuth({
  secret: "console-only", // Can be any value
  database: drizzleAdapter(db, { provider: "pg", schema }),
  plugins: [], // Add your plugins
});

// Export instances array
export default [
  {
    id: "production",
    name: "Production",
    env: "production",
    auth,
  },
];

// Cleanup handler
export const shutdownHandlers = {
  production: () => client.end(),
};

Instance Properties

Each instance requires:

PropertyTypeDescription
idstringUnique identifier (used in URLs)
namestringDisplay name in the console UI
authBetterAuthInstanceYour configured better-auth instance
envstring (optional)Environment label (production, staging, development)

Environment Variables

Store database URLs in .env:

.env
PROD_DATABASE_URL=postgresql://user:password@host:5432/myapp_prod
STAGING_DATABASE_URL=postgresql://user:password@host:5432/myapp_staging
DEV_DATABASE_URL=postgresql://user:password@localhost:5432/myapp_dev

Then reference them in your config:

const prodClient = postgres(process.env.PROD_DATABASE_URL!);
const stagingClient = postgres(process.env.STAGING_DATABASE_URL!);

The console uses dotenv to load environment variables. Make sure your .env file is in the project root.

Database Adapters

import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import * as schema from "./path/to/schema";

const client = postgres(process.env.DATABASE_URL!);
const db = drizzle(client, { schema });

const auth = betterAuth({
  secret: "console-only",
  database: drizzleAdapter(db, { provider: "pg", schema }),
});
import { prismaAdapter } from "better-auth/adapters/prisma";
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

const auth = betterAuth({
  secret: "console-only",
  database: prismaAdapter(prisma, { provider: "postgresql" }),
});

Plugin Configuration

Add the same plugins you use in your application:

import { organization, admin, apiKey } from "better-auth/plugins";

const auth = betterAuth({
  secret: "console-only",
  database: drizzleAdapter(db, { provider: "pg", schema }),
  plugins: [
    organization({ teams: { enabled: true } }),
    admin(),
    apiKey(),
  ],
});

The console auto-detects installed plugins and shows relevant UI sections. See Plugins for details.

Schema Requirements

Your schema must match your better-auth database. Import your existing schema:

// If your schema is in your app
import * as schema from "./apps/web/lib/schema";

// Or import from a shared package
import * as schema from "@myorg/db/schema";

The schema column naming (camelCase vs snake_case) must match your database. The console respects your existing conventions.

Shutdown Handlers

Export cleanup functions to properly close database connections:

export const shutdownHandlers = {
  production: () => prodClient.end(),
  staging: () => stagingClient.end(),
};

These are called when the server shuts down to prevent connection leaks.

Secret Value

The secret field is required by better-auth but not used by the console (which only reads data). You can use any placeholder value:

const auth = betterAuth({
  secret: "console-adapter-only",
  // ...
});

Next Steps