Better Auth UI Companion
Add Better Auth UI pages and optional feature plugins to an application that already runs Better Auth.
Best for
Teams already operating Better Auth that want its auth and account UI composed into the maintained BTST framework paths.
Add auth and account routes to a BTST client stack that already has a Better Auth backend.
BTST supplies
- Auth and account route definitions backed by @btst/better-auth-ui
- Sign-in, sign-up, recovery, account, security, and settings UI
- A CLI scaffold that creates one browser client for the existing auth endpoint
- Framework-native session refresh wiring for the maintained integration paths
You supply
- An existing Better Auth server, schema, migrations, providers, and secrets
- A Better Auth browser client configured for the adopter-owned endpoint
- Any optional Better Auth server and client plugins used by the application
- Deployment, session policy, and separate BTST authorization mapping when needed
You own and customize
Your application keeps the Better Auth server, database, providers, secrets, sessions, and deployment. The companion supplies client routes and UI; it does not create or host authentication.
Compatibility and dependencies
Maintained: Next.js 15+ App Router, React Router v7, TanStack Start.
Requires: An existing Better Auth backend and browser client; The supported @btst/better-auth-ui and Better Auth package cohort.
External services: The adopter's existing Better Auth endpoint; BTST does not host it.
From registration to result
A semantic workflow, not a setup shortcut
- 1Operate Better Auth
Keep the existing server endpoint, schema, providers, secrets, and browser client.
- 2Add the companion
Register auth and account client plugins in the BTST client stack.
- 3Mount routes
Serve sign-in, recovery, account, security, and settings views under your site path.
- 4Refresh sessions
Use the generated framework-native refresh seam after session changes.
@btst/better-auth-ui
is the separately maintained Better Auth UI plugin package for BTST v4. It adds
resolved auth, account, organization, and admin routes while Better Auth UI continues to read its own
session and native permissions from your Better Auth client.
This integration assumes your application already owns a Better Auth server endpoint. It does not generate a Better Auth backend, database adapter, schema, migrations, authentication providers, secrets, or deployment configuration.
Generate the minimal integration
Select the companion explicitly; it is never part of the default scaffold.
npx @btst/codegen init --plugins better-auth-uiThe generated result:
- registers only
authClientPlugin()andaccountClientPlugin(); - creates one browser client for the existing
/api/authendpoint; - mounts routes under the resolved BTST site path (
/pages/auth/*and/pages/account/*by default); - configures API, site, and QueryClient runtime only once in
createClientStack(); and - refreshes the framework explicitly after a Better Auth session change.
Organization, admin, API-key, passkey, multi-session, billing, and other Better Auth extensions remain opt-in. Configure the matching Better Auth server and client plugins before enabling their UI. The default generated scaffold remains auth and account only.
Supported release cohort
@btst/better-auth-ui@3.0.1 packages the React/shadcn components from upstream
Better Auth UI 1.7.26. Install it with the BTST v4 cohort:
| Package | Version |
|---|---|
@btst/stack, @btst/codegen | 4.5.1 |
@btst/better-auth-ui | 3.0.1 |
better-auth, @better-auth/core | 1.7.6 |
@better-auth/api-key, @better-auth/passkey | 1.7.6 |
@better-auth/utils | 0.4.2 |
@better-fetch/fetch | 1.3.2 |
better-call | 1.4.0 |
@btst/db and BTST database adapters | 3.0.0 |
| React and React DOM | >=19.2.6 |
| Tailwind CSS | >=4.3.2 |
@tanstack/react-query, @tanstack/query-core | 5.102.0 (tested cohort) |
For a manual installation, add the companion and exact auth cohort alongside your existing BTST dependencies:
pnpm add --save-exact @btst/better-auth-ui@3.0.1 \
@tanstack/react-query@5.102.0 @tanstack/query-core@5.102.0 \
better-auth@1.7.6 @better-auth/core@1.7.6 \
@better-auth/api-key@1.7.6 @better-auth/passkey@1.7.6 \
@better-auth/utils@0.4.2 @better-fetch/fetch@1.3.2 better-call@1.4.0API-key and passkey packages provide upstream type declarations; installing
them does not enable their server or client features. Component dependencies
are included in the companion package. Resolve remaining peer requirements
against its published manifest. The direct cohort above must remain aligned.
Upstream agent-auth and better-call also install their own supported versions
of better-call and @better-auth/utils; those nested implementation dependencies
can coexist and should not be forced to the application's direct versions.
Browser client and resolved routes
The CLI generates the following application-owned seam:
import { createAuthClient } from "better-auth/react"
export function createAppAuthClient(baseURL?: string) {
return createAuthClient({
...(baseURL ? { baseURL } : {}),
basePath: "/api/auth",
})
}Change basePath only when your existing Better Auth handler uses a different
path. The companion route bases are not configured here: they derive from the
site runtime passed once to createClientStack().
import { accountClientPlugin, authClientPlugin } from "@btst/better-auth-ui/client"
import { createClientStack } from "@btst/stack/client"
return createClientStack({
api: { baseURL: apiOrigin, basePath: "/api/data" },
site: { baseURL: siteOrigin, basePath: "/pages" },
queryClient,
plugins: {
auth: authClientPlugin(),
account: accountClientPlugin(),
},
})Provider overrides
The resolved stack infers plugin override keys. Configure the Better Auth client
and upstream feature plugins once under auth. Account routes do not require
an account: true flag.
<StackProvider
stack={browserStack}
router={frameworkRouter}
overrides={{
auth: {
authClient,
redirectTo: "/pages/account/account",
onSessionChange: refreshThroughTheFramework,
},
}}
>
{children}
</StackProvider>Use the framework-native synchronization generated for your target:
onSessionChange: () => router.refresh()onSessionChange: () => revalidator.revalidate()onSessionChange: () => router.invalidate()The bridge performs no hidden BTST identity refetch. If business plugins use
BTST authorization, map the Better Auth session separately with BTST's generic
createClientAuth and createServerAuth contracts and keep server
authorization authoritative.
Optional feature families
The package includes upstream auth methods (phone, wallet, device, and agent
authorization), admin pages, organization management, audit logs, SSO, OAuth
client management and consent, and billing. Register organizationClientPlugin()
or adminClientPlugin() in the BTST client stack when those route families are
needed. Enable their upstream UI feature plugins through overrides.auth.plugins.
Only configured views render; disabled feature routes do not request feature data.
BTST supplies the components, pages, routing, notifications, localization, and shared query client. Applications configure the matching Better Auth backend plugins, external providers and credentials, and authorization rules. In particular, an admin page does not grant admin access; the Better Auth backend continues to enforce permissions.
Migrating from companion v2
- Update the complete dependency cohort above, including React and Tailwind.
- Keep the
authClientPlugin(),accountClientPlugin(), andorganizationClientPlugin()registration pattern. - Move flat feature flags into upstream UI plugins in
overrides.auth.plugins. - Replace
overrides.auth.emailVerification: truewithoverrides.auth.emailAndPassword: { requireEmailVerification: true }when email/password sign-up requires verification. Keep the matching native Better Auth server requirement and email delivery configuration; the UI flag controls the post-sign-up destination, while the server enforces access. - Remove
account: truefrom provider overrides. - The default account settings URL changes from
/pages/account/settingsto/pages/account/account. Preserve existing links by settingoverrides.auth.viewPaths.settings.accountto"settings", or update links to the new default (adjust/pagesfor the configured site mount). - Use upstream
Auth,Settings,Organization, andAdmincomponents when embedding UI directly. See the companion migration guide for feature-specific configuration and removed component names.
For an existing application that keeps /pages/account/settings, use the same
view path in its BTST auth overrides and any standalone AuthProvider that renders
account links, such as a header UserButton:
const viewPaths = {
settings: { account: "settings" },
auth: { verifyEmail: "email-verification" },
}
// Pass as StackProvider's overrides.auth.
const authOverrides = {
authClient,
viewPaths,
redirectTo: "/pages/account/settings",
onSessionChange: refreshThroughTheFramework,
}The auth mapping preserves /pages/auth/email-verification; its new default is
/pages/auth/verify-email.
Page overrides use the configured URL segment too: with this mapping, account
page props belong under overrides.account.pageProps["settings"].