libSQL Auth Server setup

Stand up email and password authentication on a libSQL database in a few minutes. The database ships pre-loaded with the Better Auth schema, so there is no migration step.

1. Create the database

On the Create Database page, pick libSQL and toggle Set up as Auth Server. The provisioned database comes with the Better Auth tables (user, session, account, verification) already created.

2. Seed an admin user (optional)

Expand Seed an admin user and enter an email and password (8+ characters). The user is created with the password hashed (scrypt), so you can sign in immediately after the database finishes provisioning. The password is used once to compute the hash and is never stored or logged.

3. Connect with Better Auth

Copy LIBSQL_URL and LIBSQL_AUTH_TOKEN from the database's connection panel into your environment, then:

pnpm add better-auth @libsql/client @libsql/kysely-libsql kysely
// auth.ts
import { betterAuth } from 'better-auth'
import { createClient } from '@libsql/client'
import { LibsqlDialect } from '@libsql/kysely-libsql'

export const auth = betterAuth({
  database: {
    dialect: new LibsqlDialect({
      client: createClient({
        url: process.env.LIBSQL_URL!,
        authToken: process.env.LIBSQL_AUTH_TOKEN,
      }),
    }),
    type: 'sqlite',
  },
  emailAndPassword: { enabled: true },
})

The client SDK reads like Supabase's:

import { createAuthClient } from 'better-auth/client'
export const authClient = createAuthClient()

await authClient.signUp.email({ email, password, name })
await authClient.signIn.email({ email, password })

Prefer Auth.js or another stack?

The database detail page ships copy-paste recipes for Auth.js (Drizzle, Kysely, Prisma), a raw @libsql/client recipe, and Python (FastAPI). Those libraries manage their own schema, so run them on a fresh libSQL database created without the Auth Server preset to avoid table conflicts with the seeded Better Auth schema.

Troubleshooting

  • Seeded admin can't sign in: wait a few seconds after creation. Seeding runs right after the database becomes healthy.
  • Table already exists errors: you are likely running an Auth.js or raw recipe against an Auth Server database. Use a fresh non-preset database for those.