Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Add authentication to any framework with Better Auth. Use when a user asks to implement auth, set up login/signup, add OAuth providers, implement session management, or choose between auth libraries for TypeScript apps.
.claude/skills/terminalskills-better-auth/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | -4% | 0% |
| case-18 | ✗→✓ | ▲ Improved | -8% | 0% |
| case-10 | ✓→✗ | ▼ Worse | -16% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 21% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 74% | 0% |
Better Auth is a framework-agnostic TypeScript authentication library. It handles email/password, OAuth (Google, GitHub, Discord, etc.), magic links, two-factor auth, sessions, and organization/team management. One library, any framework, any database.
bashnpm install better-auth
typescript// lib/auth.ts — Better Auth server setup import { betterAuth } from 'better-auth' import { prismaAdapter } from 'better-auth/adapters/prisma' import { prisma } from './db' export const auth = betterAuth({ database: prismaAdapter(prisma, { provider: 'postgresql' }), emailAndPassword: { enabled: true, minPasswordLength: 8, }, socialProviders: { google: { clientId: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET!, }, github: { clientId: process.env.GITHUB_CLIENT_ID!, clientSecret: process.env.GITHUB_CLIENT_SECRET!, }, }, session: { expiresIn: 60 * 60 * 24 * 7, // 7 days updateAge: 60 * 60 * 24, // refresh every 24h }, // Plugins for additional features plugins: [], })
typescript// app/api/auth/[...all]/route.ts — Next.js API handler import { auth } from '@/lib/auth' import { toNextJsHandler } from 'better-auth/next-js' export const { GET, POST } = toNextJsHandler(auth)
typescript// lib/auth-client.ts — Client-side auth import { createAuthClient } from 'better-auth/react' export const authClient = createAuthClient({ baseURL: process.env.NEXT_PUBLIC_APP_URL, }) // React hooks export const { useSession, signIn, signUp, signOut } = authClient
tsx// components/LoginForm.tsx — Login with email or OAuth import { signIn } from '@/lib/auth-client' export function LoginForm() { return ( <div> <form onSubmit={async (e) => { e.preventDefault() const form = new FormData(e.currentTarget) await signIn.email({ email: form.get('email') as string, password: form.get('password') as string, }) }}> <input name="email" type="email" required /> <input name="password" type="password" required /> <button type="submit">Sign In</button> </form> <button onClick={() => signIn.social({ provider: 'google' })}> Continue with Google </button> <button onClick={() => signIn.social({ provider: 'github' })}> Continue with GitHub </button> </div> ) }
typescript// middleware.ts — Next.js route protection import { auth } from '@/lib/auth' import { headers } from 'next/headers' export async function getSession() { const session = await auth.api.getSession({ headers: await headers(), }) return session } // In a server component or page const session = await getSession() if (!session) redirect('/login')
npx better-auth generate to create database migrations for auth tables.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 17,621 | 10,500 | -40% | 1 | 1 | 0% | 4,364 | 2,848 | -35% | 0 | 0 | — |
case-02 | pass→pass | 6,460 | 2,910 | -55% | 1 | 1 | 0% | 1,247 | 1,509 | +21% | 0 | 0 | — |
case-03 | pass→pass | 5,600 | 3,894 | -30% | 1 | 1 | 0% | 995 | 1,731 | +74% | 0 | 0 | — |
case-04 | pass→pass | 8,768 | 4,504 | -49% | 1 | 1 | 0% | 1,759 | 1,767 | +0% | 0 | 0 | — |
case-05 | pass→pass | 6,623 | 3,395 | -49% | 1 | 1 | 0% | 1,244 | 1,578 | +27% | 0 | 0 | — |
case-06 | pass→pass | 9,345 | 6,968 | -25% | 1 | 1 | 0% | 1,806 | 2,098 | +16% | 0 | 0 | — |
case-07 | fail→pass | 6,409 | 2,798 | -56% | 1 | 1 | 0% | 1,151 | 1,108 | -4% | 0 | 0 | — |
case-08 | pass→pass | 10,495 | 5,999 | -43% | 1 | 1 | 0% | 1,955 | 2,024 | +4% | 0 | 0 | — |
case-09 | pass→pass | 11,580 | 6,357 | -45% | 1 | 1 | 0% | 2,568 | 2,315 | -10% | 0 | 0 | — |
case-10 | pass→fail | 7,060 | 1,477 | -79% | 1 | 1 | 0% | 1,388 | 1,168 | -16% | 0 | 0 | — |
case-11 | pass→pass | 12,065 | 11,467 | -5% | 1 | 1 | 0% | 2,162 | 3,297 | +52% | 0 | 0 | — |
case-12 | pass→pass | 4,765 | 4,338 | -9% | 1 | 1 | 0% | 849 | 1,783 | +110% | 0 | 0 | — |
case-13 | pass→pass | 10,190 | 5,194 | -49% | 1 | 1 | 0% | 2,080 | 1,958 | -6% | 0 | 0 | — |
case-14 | pass→pass | 9,264 | 5,096 | -45% | 1 | 1 | 0% | 1,854 | 1,947 | +5% | 0 | 0 | — |
case-15 | pass→pass | 4,606 | 2,142 | -53% | 1 | 1 | 0% | 974 | 1,332 | +37% | 0 | 0 | — |
case-16 | pass→pass | 9,102 | 4,452 | -51% | 1 | 1 | 0% | 2,033 | 1,939 | -5% | 0 | 0 | — |
case-17 | pass→pass | 2,079 | 1,673 | -20% | 1 | 1 | 0% | 349 | 1,176 | +237% | 0 | 0 | — |
case-18 | fail→pass | 7,294 | 2,441 | -67% | 1 | 1 | 0% | 1,515 | 1,391 | -8% | 0 | 0 | — |
case-19 | pass→pass | 3,954 | 2,923 | -26% | 1 | 1 | 0% | 769 | 1,317 | +71% | 0 | 0 | — |
case-20 | pass→pass | 3,967 | 2,559 | -35% | 1 | 1 | 0% | 780 | 1,333 | +71% | 0 | 0 | — |
case-21 | pass→pass | 5,542 | 1,548 | -72% | 1 | 1 | 0% | 700 | 1,186 | +69% | 0 | 0 | — |
case-22 | pass→pass | 3,256 | 1,929 | -41% | 1 | 1 | 0% | 628 | 1,239 | +97% | 0 | 0 | — |
case-23 | pass→pass | 10,396 | 9,031 | -13% | 1 | 1 | 0% | 2,311 | 2,974 | +29% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +4 percentage points is the difference between those two pass rates over the 23 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.