GUIDES

Step-by-step guides for self-hosting and getting started with your framework.

AVAILABLE GUIDES

SELF-HOST SETUP

What is self-hosting?

Self-hosting runs the studio inside your app so it’s available at a URL you choose (e.g. /api/studio or /admin). Only people who pass your access rules (roles or allowlisted emails) can open it. The studio is served by your framework, so it works in production without a separate process.

Prerequisites (starting from scratch)

Before adding the studio you need:

  • 1. A project using Better Auth (with auth exported from e.g. lib/auth.ts or src/auth.ts).
  • 2. A database and adapter (Prisma, Drizzle, or SQLite) already configured in that auth.
  • 3. Node 18+ and pnpm (or npm/yarn).

Step-by-step

Step 1: Install the package

Use a regular dependency (not dev) so the studio is available in production.

pnpm add better-auth-studio

Step 2: Generate the config file

From your project root, run the init command. It will create studio.config.ts (or studio.config.js) and, for some frameworks, the route file.

pnpx better-auth-studio init

Step 3: Point config to your auth

Open studio.config.ts and set auth to your Better Auth instance (e.g. import { auth } from "./lib/auth").

Step 4: Mount the studio in your app

Depending on your framework, you mount the handler on a path that matches basePath in config (default /api/studio). For exact code per framework, see the Next.js guide below or the Self-hosting page.

Customizing self-host

In studio.config.ts you can change:

  • basePath – URL path where the studio is served (e.g. /admin). Your route must match this.
  • access.roles – Only users with these Better Auth roles can open the studio.
  • access.allowEmails – Only these emails can open the studio (ignored if roles is set).
  • metadata – Title, logo, theme (dark/light/auto), and other UI options.

For every option, see the Customize the studio guide.

NEXT.JS – FROM SCRATCH

Prerequisites

You need a Next.js app (App Router) with Better Auth already set up:

  • Next.js 14+ with App Router
  • Better Auth installed and configured (e.g. lib/auth.ts)
  • Database and adapter (Prisma, Drizzle, or SQLite) configured in your auth

From scratch: 1. Create app and auth

If you don’t have a project yet:

pnpm create next-app@latest my-app --typescript --tailwind --eslint --app --src-dir

Then add Better Auth and your database adapter (see Better Auth docs). You should end up with something like src/lib/auth.ts (or lib/auth.ts) exporting auth and an API route for auth (e.g. app/api/auth/[...all]/route.ts).

From scratch: 2. Install Better Auth Studio

Install as a regular dependency so it runs in production:

pnpm add better-auth-studio

For local-only use you can use pnpm add -D better-auth-studio and run pnpm better-auth-studio start instead of embedding the route.

From scratch: 3. Config and API route

Run the init command to generate the config and, for Next.js, the API route file:

pnpx better-auth-studio init

It creates studio.config.ts at the project root and app/api/studio/[[...path]]/route.ts. The route file should look like this:

import { betterAuthStudio } from "better-auth-studio/nextjs";
import studioConfig from "@/studio.config";

const handler = betterAuthStudio(studioConfig);

export { handler as GET, handler as POST, handler as PUT, handler as DELETE, handler as PATCH };

If your config lives elsewhere, change the import (e.g. from "@/studio.config" or from "../../studio.config").

From scratch: 4. Run and open

pnpm dev

Open http://localhost:3000/api/studio (or the basePath you set in studio.config.ts). You’ll be asked to sign in; only users who match your access config can use the studio.

Customizing the Next.js setup

  • Different URL:In studio.config.ts set basePath: "/admin" (or another path).Then move the route to app/api/admin/[[...path]]/route.ts so the route path matches basePath.
  • Who can access: Use access.roles (e.g. ["admin"]) or access.allowEmails in the config. See the Customize the studio guide.
  • Title, logo, theme: Set metadata.title, metadata.logo, metadata.theme in config.

OTHER FRAMEWORKS

Supported frameworks

Same flow: install better-auth-studio, run pnpx better-auth-studio init to get studio.config.ts, then mount the framework adapter on the path that matches basePath (e.g. /api/studio).

From scratch (any framework)

  1. Create or open your project and set up Better Auth (auth instance + database).
  2. pnpm add better-auth-studio
  3. pnpx better-auth-studio init – creates studio.config.ts. Point it at your auth.
  4. Import the adapter (e.g. better-auth-studio/hono, better-auth-studio/express) and mount the handler on basePath.

Adapter imports

  • Hono better-auth-studio/hono
  • Express better-auth-studio/express
  • Elysia better-auth-studio/elysia
  • SvelteKit, Remix, Nuxt, Astro, Solid Start, TanStack Start – each has an entry in the package.

For exact code per framework, see the Self-hosting page and pick your framework in the tabs.

CUSTOMIZE THE STUDIO

Config file overview

All customization lives in studio.config.ts: auth, basePath, access, metadata, and optionally tools, events, lastSeenAt, ipAddress. Below is what each does and how to set it.

basePath

URL path where the studio is served. Default /api/studio. Your app must serve the handler on this path.

basePath: "/admin"

access (who can open the studio)

  • roles – Array of Better Auth role names (e.g. ["admin"]).
  • allowEmails – Array of emails allowed when not using roles.
  • sessionDuration – Studio session length (e.g. seconds).
  • secret – Secret for signing the studio session; set in production.
access: {
  roles: ["admin"],
  allowEmails: ["admin@example.com"],
  sessionDuration: 60 * 60 * 24,
  secret: process.env.STUDIO_SECRET,
}

metadata (title, logo, theme, colors)

  • title, logo, favicon
  • theme "dark" | "light" | "auto"
  • colors primary, secondary, accent
  • company name, website, supportEmail
  • features – Toggle users, sessions, organizations, analytics, tools, security
  • links [{ label, url }]
metadata: {
  title: "My Admin",
  logo: "/logo.png",
  theme: "dark",
  colors: { primary: "#0ea5e9" },
  company: { name: "Acme", supportEmail: "support@acme.com" },
  features: { tools: true, analytics: true },
}

tools (hide tools)

Use tools.exclude with ids like test-oauth, health-check, run-migration to hide them from the Tools page.

tools: { exclude: ["test-oauth", "health-check"] }

events

Optional event ingestion for the Events dashboard: events.enabled, client / clientType (prisma, drizzle, sqlite, etc.), include / exclude event types, liveMarquee.

lastSeenAt and ipAddress

lastSeenAt – Updates a “last seen” column on the user at sign-in. ipAddress – Optional IP geolocation (ipinfo, ipapi, or MaxMind file) for Events/Sessions location.

More resources