Docs

Basic Usage

Better Auth provides built-in authentication support for:

  • Email and password
  • Social provider (Google, Github, Apple, and more)

You can extend authentication options using plugins, such as: Username-based login, Passkeys, Email magic links, and more.

Email & Password

To enable email and password authentication:

auth.ts
import { betterAuth } from "better-auth"
 
export const auth = betterAuth({
    //...rest of the options
    emailAndPassword: {    
        enabled: true
    } 
})

Signup

Before a user can sign in, they need to sign up. To sign up a user using email and password, you need to call the client method signUp.email with the user's information.

Example: Using React

SignUp.tsx
import { authClient } from '@/auth'; //import the auth client
 
export default function SignUp() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [name, setName] = useState('');
  const [image, setImage] = useState<File | null>(null);
 
  const signUp = async () => {
    const res = await authClient.signUp.email({ 
        email, 
        password, 
        name, 
        image: image ? convertImageToBase64(image) : undefined,
     }, {
        onRequest: (ctx) => {
         //show loading     
        },
        onsSuccess: (ctx) => {
          //redirect to the dashboard
        },
        onError: (ctx) => {
          alert(ctx.error.message);
        },
      });
  };
 
  return (
    <div>
      <input type="name" value={email} onChange={(e) => setEmail(e.target.value)} />
      <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
      <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} />
      <input type="file" onChange={(e) => setImage(e.target.files?.[0])} />
      <button onClick={signUp}>Sign Up</button>
    </div>
  );
}

Signin

To signin a user, you can use the signIn.email function provided by the client. The signIn function takes an object with the following properties:

Example: Using Svlete

signin.svelte
<script lang="ts">
import { client } from "$lib/auth-client"; //import the auth client
import { writable } from "svelte/store";
 
const email = writable("");
const password = writable("");
 
const handleSignIn = async () => {
    await client.signIn.email({
        email: $email,
        password: $password
    }, {
        onRequest: () => {
            //show loading
        },
        onSuccess: () => {
            //redirect to dashboard
        },
        onError: (ctx) => {
            alert(ctx.error.message)
        }
    })
}
</script>
 
<div>
    <input type="email" bind:value={$email} />
    <input type="password" bind:value={$password} />
    <button on:click={handleSignIn}>
      Sign In
    </button>
</div>

Social Sign-On

Better Auth supports multiple social providers, including Google, Github, Apple, Discord, and more. To use a social provider, you need to configure the ones you need in the socialProviders option on your auth object.

auth.ts
import { betterAuth } from "better-auth"
import { github } from "better-auth/social-providers"
 
export const auth = betterAuth({
    //...rest of the options
    socialProviders: { 
       github: { 
        clientId: GITHUB_CLIENT_ID, 
        clientSecret: GITHUB_CLIENT_SECRET, 
       } 
    }, 
})

Signin with social providers

To sign in using a social provider you need to calle signIn.social method and pass the provider.

It also takes callbackURL property which is the url the user will be redirected after they signIn.

Example: Using Vue

signin.vue
<template>
  <div>
    <h2>Sign In</h2>
    <button @click="handleSignIn">Sign In with GitHub</button>
  </div>
</template>
 
<script>
import { client } from "@/auth-client"; //import the auth client
 
export default {
  name: "SignIn",
  methods: {
    async handleSignIn() {
    await client.signIn.social({
          provider: "github",
          callbackURL: "/dashboard", //redirect to dashboard after sign in
    });
    }
  }
};
</script>

Session Mangemnt

Once a user is signed in, you'll want to access their session. Better auth allows you easily to access the session data from the server and client side.

Client Side

Better Auth provides a useSession hook to easily access session data on the client side. This hook is implemented in a reactive way for each supported framework, ensuring that any changes to the session (such as signing out) are immediately reflected in your UI.

It has the following properties:

  • data: the actual session data which includes session and user object.
  • isPending: a boolean that indicates whether the session is being loaded.
  • error: an error object that contains any errors that occurred while loading the session.
user.svelte
import { client } from "~/lib/client";
client.useSession.subscribe((value)=>{
    //do something with the session
})

For more details check session-management documentation.

Server Side

The server provides a session object that you can use to access the session data. It requires request headers object to be passed to the getSession method.

Example: Using some popular frameworks

server.ts
import { auth } from "./auth";
import { headers } from "next/headers";
 
const session = await auth.api.getSession({
    headers: headers() // you need to pass the headers object. 
})

Using Plugins

One of the unique features of better auth is a plugins ecosystem. It allows you to add complex auth realted functionilty with small lines of code.

Below is an example of how to add two factor authentication using two factor plugin.

Server Configuration

To add a plugin, you need to import the plugin and pass it to the plugins option of the auth instance. For example, to add two facor authentication, you can use the following code:

auth.ts
import { betterAuth } from "better-auth"
import { twoFactor } from "better-auth/plugins"
 
export const auth = betterAuth({
    //...rest of the options
    plugins: [ 
        twoFactor({
            issuer: "my app" //your application name
       }) 
    ] 
})

now two factor related routes and method will be available on the server.

Migrate Database

once you have added the plugin, you need to migrate your database to add the necessary tables and fields. You can do this by running the following command:

npx better-auth migrate

Client Configuration

Once we're done with the server, we need to add the plugin to the client. To do this, you need to import the plugin and pass it to the plugins option of the auth client. For example, to add two facor authentication, you can use the following code:

client.ts
import { createAuthClient } from "better-auth/client";
import { twoFactorClient } from "better-auth/client/plugins";
 
const client = createAuthClient({
    plugins: [ 
        twoFactorClient({ 
            twoFactorPage: "/two-factor"
        }) 
    ] 
})

now two factor related methods will be available on the client.

profile.ts
import { client } from "./client"
 
const enableTwoFactor = async() => {
    const data = await client.twoFactor.enable({
        password // the user password is required
    }) // this will enable two factor
}
 
const disableTwoFactor = async() => {
    const data = await client.twoFactor.disable({
        password // the user password is required 
    }) // this will disable two factor
}
 
const signInWith2Factor = async() => {
    const data = await client.signIn.email({
        //...
    })
    //if the user has two factor enabled, it will redirect to the two factor page
}
 
const verifyTOTP = async() => {
    const data = await client.twoFactor.verifyTOTP({
        code: "123456", // the code entered by the user
        /**
         * If the device is trusted, the user won't 
         * need to pass 2FA again on the same device
         */
        trustDevice: true
    })
}

On this page

Edit on GitHub