Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/better-auth/better-auth/llms.txt

Use this file to discover all available pages before exploring further.

Thank you for your interest in contributing to Better Auth! This page covers everything you need to get started.

GitHub Issues

Browse open issues or report a bug.

Discord

Ask questions and discuss ideas with the community.

Development setup

Make sure you have Node.js LTS and pnpm installed before continuing.
1

Fork and clone the repository

Visit github.com/better-auth/better-auth and click Fork. Then clone your fork:
git clone https://github.com/YOUR-USERNAME/better-auth.git
cd better-auth
2

Install dependencies

pnpm install
3

Set up environment variables

cp -n ./docs/.env.example ./docs/.env
4

Create a feature branch

git remote add upstream https://github.com/better-auth/better-auth.git
git checkout canary
git pull upstream canary
git checkout -b feat/your-feature-name
5

Start the development server

# Main package
pnpm dev

# Documentation site
pnpm -F docs dev

Running tests

Better Auth uses Vitest. Test files live next to the source files they cover.
# Run a specific test file
vitest packages/better-auth/src/auth/auth.test.ts

# Run tests matching a pattern
vitest packages/better-auth/src -t "sign up"
Do not run pnpm test at the repo root — it runs all tests across all packages and takes a long time. Target specific files or patterns instead.
Adapter tests (PostgreSQL, MySQL, etc.) require Docker:
docker compose up -d
vitest e2e/adapter

Using the test instance helper

import { describe, it, expect } from "vitest";
import { getTestInstance } from "better-auth/test";

describe("my feature", () => {
  it("works as expected", async () => {
    const { client } = await getTestInstance();
    const result = await client.signUp.email({
      email: "test@example.com",
      password: "password",
      name: "Test User",
    });
    expect(result.data).toBeDefined();
  });
});
The helper also exposes runWithUser and signInWithTestUser for authenticated test scenarios:
const { client, runWithUser } = await getTestInstance();

await runWithUser("user@example.com", "password", async (headers) => {
  const session = await client.getSession({ fetchOptions: { headers } });
  expect(session.data).not.toBeNull();
});

Code style

Better Auth uses Biome for formatting and linting.
# Check formatting
pnpm format:check

# Fix formatting
pnpm format

# Lint
pnpm lint

# Fix lint issues
pnpm lint:fix

# Type check
pnpm typecheck
All CI checks must pass before a PR is merged. Run the checks locally before opening a PR:
pnpm format:check && pnpm lint && pnpm typecheck
Style rules:
  • Use tabs for indentation in TypeScript; 2 spaces in JSON.
  • Avoid any types and unsafe typecasts.
  • Prefer functions and plain objects over classes.
  • Do not use runtime-specific APIs like Buffer in library code. Use Uint8Array instead.

PR guidelines

  • Target the canary branch, not main.
  • Use Conventional Commits for commit messages:
    feat(scope): add X
    fix(scope): resolve Y
    docs: update contributing guide
    chore: bump dependencies
    
  • Keep PRs focused on a single change.
  • Add tests for new features and bug fixes.
  • Update documentation when changing public APIs.
  • If a PR fixes a numbered GitHub issue, add a JSDoc @see comment to the relevant test:
    /**
     * @see https://github.com/better-auth/better-auth/issues/1234
     */
    it("should handle the previously broken behavior", async () => { /* ... */ });
    

Contribution areas

AreaNotes
Bug fixesCheck issues labeled good first issue
Framework integrationsPrefer framework-agnostic solutions; keep minimal
Core pluginsOpen an issue to discuss before implementing
Community pluginsDevelop independently and share on Discord
DocumentationFix typos, add examples, keep docs in sync with code

Need help?