Docs

Installation

Install the Package

Let's start by adding Better Auth to your project:

npm install better-auth

If you're using a separate client and server setup, make sure to install Better Auth in both parts of your project. (currently, Better Auth only supports web platforms, but more clients will be added soon)

Set Environment Variables

Create a .env file in the root of your project and add the following environment variables:

  1. Secret Key

Random value used by the library for encryption and generating hashes. You can generate one using the button below or you can use something like openssl.

.env
BETTER_AUTH_SECRET=
  1. Set Base URL
.env
BETTER_AUTH_URL=http://localhost:3000 #Base URL of your app
  1. Trusted Origins (optional)

If the requests are coming from different origins (not the base url), you can add them to the trusted origins.

.env
BETTER_AUTH_TRUSTED_ORIGINS="http://localhost:3000,https://example.com" //Add your trusted origins here

Create A Better Auth Instance

Create a file named auth.ts in one of these locations:

  • Project root
  • lib/ folder
  • utils/ folder

You can also nest any of these folders under src/ or app/ folder. (e.g. src/lib/auth.ts, app/lib/auth.ts).

And in this file, import Better Auth and create your instance. Make sure to export the auth instance with the variable name auth or as a default export.

auth.ts
import { betterAuth } from "better-auth";
 
export const auth = betterAuth({
    //...
})

Configure Database

Better Auth requires a database to store user data. By default, it uses Kysely for database queries, supporting postgresql, mysql, and sqlite out of the box.

auth.ts
import { betterAuth } from "better-auth";
import Database from "better-sqlite3";
 
export const auth = betterAuth({
    database: new Database("./sqlite.db"),
})

You can also use any Kysely dialect in the database configuration.

Example with LibsqlDialect:

auth.ts
import { betterAuth } from "better-auth";
import { LibsqlDialect } from "@libsql/kysely-libsql";
 
const dialect = new LibsqlDialect({
    url: process.env.TURSO_DATABASE_URL || "",
    authToken: process.env.TURSO_AUTH_TOKEN || "",
})
 
export const auth = betterAuth({
  database: {
    dialect,
    type: "sqlite"
  }
});

Adapters

If your database isn’t supported by Kysely, you can use an adapter to connect. Simply import the adapter and pass it into the database option.

auth.ts
import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
import { PrismaClient } from "@prisma/client";
 
const prisma = new PrismaClient();
export const auth = betterAuth({
    database: prismaAdapter(prisma, {
        provider: "sqlite", // or "mysql", "postgresql", ...etc
    }),
});

For optimal performance, use the built-in Kysely adapter if possible.

Create Database Tables

Better Auth’s comes with a CLI tool to help manage schema required by the library.

Generate: Generates an ORM schema or SQL migration file.

Terminal
npx @better-auth/cli generate

Migrate: Directly creates the required tables in the database. (only available for Kysely adapter)

Terminal
npx @better-auth/cli migrate

see the CLI documentation for more information.

If you instead want to create the schema manually, you can find the core schema required in the database section.

Authentication Methods

Configure the authentication methods you want to use. Better Auth comes with built-in support for email/password, and social sign-on providers.

auth.ts
import { betterAuth } from "better-auth"
import { github } from "better-auth/social-providers"
 
export const auth = betterAuth({
    //...other options
    emailAndPassword: {  
        enabled: true
    },
    socialProviders: { 
       github: { 
        clientId: process.env.GITHUB_CLIENT_ID, 
        clientSecret: process.env.GITHUB_CLIENT_SECRET, 
       } 
    }, 
});

You can use even more authentication methods like passkey, username, magic link and more through plugins.

Mount Handler

To handle api requests, you need to set up a route handler on your server.

Create a new file or route in your framework's designated catch-all route handler. This route should handle requests for the path /api/auth/* (unless you've configured a different base path).

Better Auth supports any backend framework with standard Request and Response objects and offers helper functions for popular frameworks.

/app/api/auth/[...all]/route.ts
import { auth } from "@/lib/auth"; // path to your auth file
import { toNextJsHandler } from "better-auth/next-js";
 
export const { POST, GET } = toNextJsHandler(auth);

Create Client Instance

The client-side library helps you interact with the auth server. Better Auth comes with a client for all the popular web frameworks including for vanilla javascript.

  1. Import createAuthClient from the package for your framework (e.g., "better-auth/react" for React).
  2. Call the function to create your client.
  3. Pass the base url of your auth server. (If the auth server is running on the same domain as your client, you can skip this step.)

If you're using a different base path other than /api/auth make sure to pass the whole url including the path. (e.g. http://localhost:3000/custom-path/auth)

lib/auth-client.ts
import { createAuthClient } from "better-auth/react"
export const authClient = createAuthClient({
    baseURL: "http://localhost:3000" // the base url of your auth server
})

Tip: You can also export specific methods if you prefer:

export const { signIn, signUp, useSession } = createAuthClient()

🎉 That's it!

That's it! You're now ready to use better-auth in your application. Continue to basic usage to learn how to use the auth instance to sign in users.

On this page

Edit on GitHub