Better Auth UI: the complete Next.js + shadcn guide (2026)
What Better Auth UI is, how to install it with shadcn, wire AuthProvider in Next.js, protect routes, and when a full SaaS starter beats DIY auth screens.

If you searched for Better Auth UI, you are usually past the "which auth library?" debate. You already want Better Auth for sessions, OAuth, and plugins - and you do not want to hand-build every sign-in, sign-up, reset-password, and settings screen from scratch.
Short answer
Better Auth UI is an open-source, MIT-licensed set of ready-made authentication components built specifically for Better Auth. The recommended path today is the shadcn/ui registry (npx shadcn@latest add https://better-auth-ui.com/r/auth.json), with HeroUI and SolidJS variants also available. You own the generated code, style it like any shadcn component, and plug it into your Better Auth client. If you also need billing, organizations, admin, and multi-platform apps - not just auth screens - TurboStarter ships production auth views on Better Auth without assembling the rest of the SaaS stack yourself.
Key takeaways
- Better Auth = auth server. Better Auth UI = the screens.
- Prefer the 2026 shadcn registry +
AuthProviderover legacy@daveyplate/better-auth-ui/AuthUIProvidertutorials. - Protect dashboards with server
ensureSessionplus clientuseAuthenticate. - Match server plugins to
AuthProviderplugins or buttons will appear broken. - Use a SaaS starter when auth is one of many blockers, not the only one.
This guide covers what Better Auth UI is, how it differs from Better Auth itself, how to install and integrate it in Next.js App Router, which components and plugins matter in production, and when a starter kit is the better use of your time.
What is Better Auth UI?
Better Auth UI is a UI layer for Better Auth: drop-in React (and Solid) components for sign-in, sign-up, password recovery, account settings, user menus, email templates, and plugin-backed flows like magic links, passkeys, organizations, and API keys. It is maintained at better-auth-ui.com with source on GitHub.
The library is Better Auth native. It is not a generic auth kit bolted onto Clerk, Auth.js, or Supabase Auth. That focus is why people search "better auth ui" and "better auth shadcn": they want components that already speak Better Auth's client API.
Three UI stacks ship from the same project. Shared React data hooks live under @better-auth-ui/react (queries, mutations, ensureSession, useAuthenticate), so UI variants share one auth data layer.
shadcn/ui
Registry JSON via shadcn CLI. Best when you already use Tailwind + shadcn and want owned source in components/.
HeroUI
Install @better-auth-ui/heroui packages. Best when your design system is already HeroUI.
Zaidan (SolidJS)
@better-auth-ui/solid for Solid apps. Same Better Auth concepts, different UI runtime.
Better Auth vs Better Auth UI (do not confuse them)
Search results mix these two names. Treat them as a backend + UI pair: Better Auth owns sessions and plugins; Better Auth UI owns forms, settings, and account chrome. You still configure secrets, schema, email, and OAuth yourself (or inherit them from a starter).
| Piece | Role | You still own |
|---|---|---|
| Better Auth | Auth server, sessions, plugins, database adapters, API routes | Secrets, schema, email delivery, OAuth apps, security policy |
| Better Auth UI | Forms, settings cards, user button, email templates, route views | Layout, branding, which plugins are enabled in the provider |
Better Auth alone does not give you finished screens. Better Auth UI alone does not replace a configured auth instance, database, or email provider. You need both - or a starter that already wires both.
Legacy package alert
The older npm package @daveyplate/better-auth-ui is still widely referenced in tutorials and DeepWiki pages. It is the legacy distribution. Current docs steer new projects to the shadcn registry and @better-auth-ui/* packages. If you find AuthUIProvider examples online, map them to the newer AuthProvider pattern in the official Next.js guide.
Who should use Better Auth UI?
Use Better Auth UI when you already chose Better Auth and need production auth screens fast on shadcn or HeroUI. Skip it when auth is the product (bespoke identity UI), you are on another auth vendor, or you also need billing, orgs, admin, and mobile this month.
Use Better Auth UI if
- You chose Better Auth and want days, not weeks, of form work gone
- Your design system is shadcn/ui (or HeroUI) and you edit components in-repo
- You need credentials, social login, forgot/reset password, account + security settings
- You plan Better Auth plugins (magic link, passkey, organization) with matching UI
Skip or use a starter if
- Every auth pixel is unique brand IP
- You are not on Better Auth (use that vendor's UI)
- You need auth + billing + orgs + admin + mobile tomorrow
- A SaaS starter kit is faster than composing libraries
Prerequisites before you install Better Auth UI
Official docs assume these are already working. Without a live Better Auth server, email, and OAuth apps, polished forms still fail in production.
Next.js (or TanStack Start) + Tailwind - App Router is the path covered below.
shadcn/ui initialized - required for the shadcn registry install path.
Better Auth working -
auth server + authClient that can already sign in via API.
Email delivery - verification, magic links, and password reset need a provider in staging.
OAuth apps - create Google/GitHub (or others) with correct redirect URIs before enabling social buttons.
Prove auth before UI
Auth UI cannot fix a missing Resend key or a wrong Google redirect URI. Call signIn.email against your API first, then install components.
How to install Better Auth UI (shadcn path)
The fastest path for most Next.js teams is the registry install. Use the smaller registries for a thin first commit; use all.json when you want plugins and email templates immediately.
npx shadcn@latest add https://better-auth-ui.com/r/auth.jsonPulls the dynamic Auth component and views for sign-in, sign-up, forgot-password, reset-password, and sign-out.
npx shadcn@latest add https://better-auth-ui.com/r/auth.json
npx shadcn@latest add https://better-auth-ui.com/r/settings.json https://better-auth-ui.com/r/user-button.jsonAdds account/security settings and the header UserButton most SaaS apps need next.
npx shadcn@latest add https://better-auth-ui.com/r/all.jsonInstalls every component, plugin surface, and email template in one shot. Heavier first commit; fewer follow-up CLI runs.
HeroUI users install packages instead of the registry - see HeroUI quick start. Always prefer the current docs over older @daveyplate/better-auth-ui READMEs when APIs diverge.
Next.js App Router setup (AuthProvider + routes)
The official Next.js integration follows one pattern: shared React Query client โ AuthProvider โ dynamic /auth/[path] and /settings/[path] routes โ session guards. After wiring, your tree looks like this:
Step-by-step wiring
Create a factory that returns a new client per server request and a singleton in the browser so caches never leak across users:
import { QueryClient } from "@tanstack/react-query";
function makeQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
staleTime: 5_000,
},
},
});
}
let browserQueryClient: QueryClient | undefined;
export function getQueryClient() {
if (typeof window === "undefined") {
return makeQueryClient();
}
browserQueryClient ??= makeQueryClient();
return browserQueryClient;
}Follow the official example closely if your Better Auth UI version expects a TanStack helper for environment detection. The important rule is no shared QueryClient across requests on the server.
"use client";
import { QueryClientProvider } from "@tanstack/react-query";
import Link from "next/link";
import { useRouter } from "next/navigation";
import type { ReactNode } from "react";
import { authClient } from "@/lib/auth-client";
import { getQueryClient } from "@/lib/query-client";
import { AuthProvider } from "@/components/auth/auth-provider";
import { Toaster } from "@/components/ui/sonner";
export function Providers({ children }: { children: ReactNode }) {
const router = useRouter();
const queryClient = getQueryClient();
return (
<QueryClientProvider client={queryClient}>
<AuthProvider
authClient={authClient}
redirectTo="/settings/account"
socialProviders={["google", "github"]}
navigate={({ to, replace }) =>
replace ? router.replace(to) : router.push(to)
}
Link={Link}
>
{children}
<Toaster />
</AuthProvider>
</QueryClientProvider>
);
}Wire Providers in app/layout.tsx the same way you wrap theme providers. Pass framework navigate / Link so auth redirects use the App Router, not full page reloads.
import { viewPaths } from "@better-auth-ui/core";
import { notFound } from "next/navigation";
import { Auth } from "@/components/auth/auth";
export default async function AuthPage({
params,
}: {
params: Promise<{ path: string }>;
}) {
const { path } = await params;
if (!Object.values(viewPaths.auth).includes(path)) {
notFound();
}
return (
<div className="my-auto flex justify-center p-4 md:p-6">
<Auth path={path} />
</div>
);
}Default auth paths include sign-in, sign-up, sign-out, forgot-password, and reset-password.
import { viewPaths } from "@better-auth-ui/core";
import { ensureSession } from "@better-auth-ui/react/server";
import { dehydrate, HydrationBoundary } from "@tanstack/react-query";
import { headers } from "next/headers";
import { notFound, redirect } from "next/navigation";
import { Settings } from "@/components/auth/settings/settings";
import { auth } from "@/lib/auth";
import { getQueryClient } from "@/lib/query-client";
export default async function SettingsPage({
params,
}: {
params: Promise<{ path: string }>;
}) {
const { path } = await params;
if (!Object.values(viewPaths.settings).includes(path)) {
notFound();
}
const queryClient = getQueryClient();
const session = await ensureSession(queryClient, auth, {
headers: await headers(),
});
if (!session) {
redirect(
`/auth/sign-in?redirectTo=${encodeURIComponent(`/settings/${path}`)}`,
);
}
return (
<HydrationBoundary state={dehydrate(queryClient)}>
<div className="mx-auto w-full max-w-3xl p-4 md:p-6">
<Settings path={path} />
</div>
</HydrationBoundary>
);
}ensureSession hydrates the React Query cache during SSR so client hooks skip a loading flash. Settings paths typically include account and security.
Protecting routes with Better Auth UI
You need two layers for production SaaS dashboards: a server check so HTML never streams to anonymous users, and a client hook so sessions that die mid-visit still redirect. Official docs recommend SSR guard + useAuthenticate together.
Check the session in an async server component before streaming HTML. Redirect unauthenticated users immediately - no flash of dashboard chrome.
import { ensureSession } from "@better-auth-ui/react/server";
import { dehydrate, HydrationBoundary } from "@tanstack/react-query";
import { headers } from "next/headers";
import { redirect } from "next/navigation";
import { auth } from "@/lib/auth";
import { getQueryClient } from "@/lib/query-client";
export default async function Dashboard() {
const queryClient = getQueryClient();
const session = await ensureSession(queryClient, auth, {
headers: await headers(),
});
if (!session) {
redirect("/auth/sign-in?redirectTo=/dashboard");
}
return (
<HydrationBoundary state={dehydrate(queryClient)}>
<h1>Hello, {session.user.email}</h1>
</HydrationBoundary>
);
}Server checks only run on navigation. For sign-out in another tab, expired sessions, or statically prerendered routes, use useAuthenticate so the UI redirects when the session disappears.
"use client";
import { useAuth, useAuthenticate } from "@better-auth-ui/react";
export function DashboardClient() {
const { authClient } = useAuth();
const { data: session } = useAuthenticate(authClient);
if (!session) {
return null; // hook redirects; show a spinner while it settles
}
return <p>{session.user.email}</p>;
}Header UserButton tip
If a header or sidebar reads the session outside a protected page, prefetch the session in that subtree's server parent and wrap it in its own HydrationBoundary. Otherwise those components trigger a fresh client fetch on mount.
Better Auth UI components worth knowing
From the project llms.txt / docs index, the shadcn surface covers auth views, account chrome, settings, and email templates. Enable only what your Better Auth server already supports - a passkey button with no passkey plugin is a support ticket waiting to happen.
Auth surfaces
Auth- path-driven shell for all auth viewsSignIn/SignUp- credentials, magic link, socialForgotPassword/ResetPassword- recovery flowVerifyEmail- confirmation + resend cooldownSignOut- mounts and signs the user out
Account chrome
UserButton- avatar menu + sign outUserAvatar/UserView- display primitives for headers and sidebars
Settings
- Account - profile, change email
- Security - change password, linked accounts, active sessions
Email templates
React Email-style templates for verification, magic link, reset password, OTP, new device, and organization invites - so UI and transactional mail feel like one product.
Plugins that expand the Better Auth UI surface
Better Auth UI plugins mirror Better Auth capabilities. Wire plugins on the server (Better Auth) and in AuthProvider (UI). Mismatched plugin lists are a top source of "button does nothing" bugs.
| Plugin | What the UI adds |
|---|---|
| Magic Link | Passwordless email sign-in |
| Passkey | WebAuthn register / sign-in / device management |
| Organization | Multi-tenant members, invites, roles |
| Username | Username sign-in + availability checks |
| API Key | Create, copy, revoke keys in settings |
| Captcha | Bot protection on auth forms |
| Delete User | Account deletion with confirmation |
| Multi Session | Switch between concurrent accounts |
| Theme | Light / dark / system in settings |
Customization: own the code, keep the behavior
Because the shadcn path copies components into your repo, customization is normal product work. Prefer provider props and plugins over forking mutation logic so upstream registry updates stay mergeable.
Tokens - change CSS variables / Tailwind theme; auth cards follow the rest of the app.
Copy - localization props / strings for product language (not generic "Sign in").
Fields - additional fields on sign-up and profile when your user model needs them.
Layout - wrap Auth in your marketing shell, split-pane brand panel, or
modal; keep form logic intact.
Providers - set socialProviders and Better Auth social configs to the
same list.
Better Auth UI vs DIY shadcn forms vs a SaaS starter
This is the decision most "better auth ui" searchers are actually making. Pick Better Auth UI when auth screens are the bottleneck. Pick a starter when auth is one of ten blockers. Pick DIY when auth is the product.
DIY forms
Days to weeks. Full visual control. You maintain every edge case: errors, loading, 2FA, OAuth return.
Better Auth UI
Hours. Polished auth + settings components. Still DIY for billing, orgs product UX, admin, and mobile.
TurboStarter
Minutes for the whole foundation. Better Auth flows + billing + orgs + admin + web/mobile/extension monorepo.
| Approach | Time to usable auth UI | You also get | Tradeoff |
|---|---|---|---|
DIY forms calling authClient | Days-weeks | Full visual control | You maintain every edge case |
| Better Auth UI | Hours | Polished auth + settings components | Still DIY for billing, orgs, admin, mobile |
| TurboStarter | Minutes for the whole foundation | Better Auth + billing + orgs + admin + multi-platform | Broader kit than "just auth components" |
See TurboStarter's auth overview and user flow for password, magic link, OTP, passkeys, OAuth, and 2FA views that ship with the kit.
Production checklist for Better Auth UI
Use this before you call auth "done":
Better Auth server + client share the same base URL and trusted origins
Email provider sends verification / reset / magic-link messages in staging
AuthProvider plugins match server pluginsDashboard uses ensureSession (or equivalent server check) - not
client-only gates
useAuthenticate covers long-lived client shells (headers with
UserButton)
Session cookies work across your real deploy host (HTTPS, correct domain)
Accessibility: labels, errors, and focus order checked on sign-in / sign-up
For a broader Next.js hardening pass after auth UI lands, read the Next.js security checklist.
Common Better Auth UI mistakes
- Installing UI before Better Auth works - prove
signIn.emailagainst your API first - Client-only route protection - scrapers and prefetch still hit RSC payloads; guard on the server
- Shared QueryClient on the server - session cache leaks across users under load
- Legacy package docs on a new install -
AuthUIProvidertutorials may not match currentAuthProvider+ registry files - Enabling social buttons without provider credentials - empty OAuth config fails late, in the redirect
- Forgetting
redirectTo- users bounce to/after login instead of the page they wanted - Treating auth UI as the whole SaaS - you still need billing webhooks, org invites, and admin tools
Related reading
Best SaaS stack 2026
Where Better Auth sits next to Next.js, Drizzle, Hono, and billing in a production monorepo.
Next.js security checklist
Harden auth, APIs, CSRF/XSS, and sessions after your Better Auth UI screens ship.
TurboStarter auth docs
Password, OAuth, MFA, passkeys, and ready-made auth views in the Core Kit.
Best SaaS starter kits 2026
Compare boilerplates when you need more than auth components.
Frequently asked questions
Better Auth UI is an open-source component library that provides ready-made authentication and account UI for the Better Auth framework. It ships shadcn/ui, HeroUI, and SolidJS variants so you can drop in sign-in, sign-up, recovery, settings, and related flows instead of building them from scratch.
Yes. Better Auth UI is MIT-licensed open source. You can use it commercially. You still pay for your own hosting, database, email, and OAuth provider costs - the UI library itself is free.
Yes. Official docs cover App Router integration with AuthProvider, dynamic /auth/[path] routes, React Query hydration, ensureSession on the server, and useAuthenticate on the client. Follow better-auth-ui.com/docs/shadcn/integrations/nextjs.
New projects should follow the current better-auth-ui.com docs (shadcn registry and @better-auth-ui/* packages). @daveyplate/better-auth-ui is the widely installed legacy package; use it only if you are maintaining an existing app already on that API, or migrate deliberately.
Yes on the shadcn path - components are copied into your repo. Change Tailwind tokens, localization strings, layout wrappers, and additional fields. Keep provider wiring and mutations aligned with Better Auth so security behavior stays correct.
The UI supports those flows through plugins (organization, passkey, and others) when the matching Better Auth server plugins are enabled. Install the plugin UI, configure AuthProvider, and verify server + client plugins match.
Choose Better Auth UI when authentication screens are your gap. Choose a starter like TurboStarter when you also need billing, teams, admin, emails, marketing pages, and optionally mobile or extension apps on the same Better Auth foundation.
The project links a demo from better-auth-ui.com (see also demo.better-auth-ui.com). For a full SaaS product surface on Better Auth - not only auth components - try demo.turbostarter.dev.
Use ensureSession from @better-auth-ui/react/server in async server components to redirect before HTML streams, then add useAuthenticate on the client for live session changes. Together they cover first paint and mid-session expiry.
Conclusion
Better Auth UI is the missing presentation layer for Better Auth: shadcn-owned (or HeroUI/Solid) components for the auth and account flows every SaaS ships. Install the registry, wrap AuthProvider, add dynamic auth and settings routes, and protect dashboards with ensureSession plus useAuthenticate.
If your goal is only clean auth screens on an existing Next.js app, start with the official Better Auth UI docs. If your goal is a production SaaS - auth UI plus billing, organizations, admin, and a monorepo you can grow into mobile - skip wiring ten libraries and start from TurboStarter.
Best SaaS starter kit 2026: 9 boilerplates compared
Compare the best SaaS starter kits in 2026 by stack, pricing, auth, billing, teams, AI readiness, and long-term maintainability.
Next.js Security Checklist 2026: Auth, API, CSRF & XSS (Complete Guide)
Production-ready Next.js security for SaaS - auth hardening, API protection, CSRF/XSS. Patterns from TurboStarter's stack.



