CtrlK
BlogDocsLog inGet started
Tessl Logo

pleaseai/better-auth

Better Auth authentication framework skills for JavaScript/TypeScript projects

72

Quality

91%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files

plugins.mdskills/use-better-auth/references/

Built-in Plugins

Every row below was verified against $(ask src better-auth)/packages/better-auth/src/plugins/ and each plugin's index.ts exports. Re-run this before trusting any import path for the version in use:

SRC=$(ask src better-auth)
ls "$SRC/packages/better-auth/src/plugins"
rg "^export (const|function) " "$SRC/packages/better-auth/src/plugins/*/index.ts"

Plugins live in the main better-auth package unless marked otherwise. Each server plugin is added to betterAuth({ plugins: [...] }); each matching client plugin is added to createAuthClient({ plugins: [...] }) so the client SDK surfaces the new endpoints with types.

Multi-tenant / teams

organization

Server: import { organization } from "better-auth/plugins/organization" Client: import { organizationClient } from "better-auth/client/plugins"

Adds orgs, members, roles, invitations, and team-scoped sessions. Ships a companion access-control module (access — see below) for defining role statements.

Use when the app has multiple tenants, workspaces, or teams. Skip for single-tenant apps with a flat user list.

Authentication factors

two-factor

Server: import { twoFactor } from "better-auth/plugins/two-factor" Client: import { twoFactorClient } from "better-auth/client/plugins"

TOTP + backup codes + optional OTP. Adds /two-factor/* endpoints.

passkey (separate package @better-auth/passkey)

Server: import { passkey } from "@better-auth/passkey" Client: import { passkeyClient } from "@better-auth/passkey/client"

WebAuthn passkey registration and sign-in. Not in better-auth/plugins/ — it ships as its own package. Confirm with ls $(ask src better-auth)/packages/passkey.

magic-link

Server: import { magicLink } from "better-auth/plugins/magic-link" Client: import { magicLinkClient } from "better-auth/client/plugins"

Passwordless email links. Requires providing sendMagicLink({ email, url, token }) — mail delivery is owned by the caller.

email-otp

Server: import { emailOTP } from "better-auth/plugins/email-otp" Client: import { emailOTPClient } from "better-auth/client/plugins"

Email OTP for verification / sign-in / password reset. Requires a sendVerificationOTP callback.

phone-number

Server: import { phoneNumber } from "better-auth/plugins/phone-number" Client: import { phoneNumberClient } from "better-auth/client/plugins"

Phone + OTP sign-in. Requires a sendOTP callback — pair with Twilio, Vonage, etc.

siwe

Server: import { siwe } from "better-auth/plugins/siwe" Client: import { siweClient } from "better-auth/client/plugins"

Sign-In With Ethereum (EIP-4361). Needs getNonce / verifyMessage callbacks.

one-tap

Server: import { oneTap } from "better-auth/plugins/one-tap" Client: import { oneTapClient } from "better-auth/client/plugins"

Google One Tap sign-in.

anonymous

Server: import { anonymous } from "better-auth/plugins/anonymous" Client: import { anonymousClient } from "better-auth/client/plugins"

Creates throw-away users before sign-up; upgrades them to real accounts on credential linking.

username

Server: import { username } from "better-auth/plugins/username" Client: import { usernameClient } from "better-auth/client/plugins"

Adds username field + username-based sign-in alongside email.

OAuth / OIDC

generic-oauth

Server: import { genericOAuth } from "better-auth/plugins/generic-oauth" Client: import { genericOAuthClient } from "better-auth/client/plugins"

Catch-all for OAuth 2 / OIDC providers not in social-providers/. Ships pre-built configs for Auth0, Slack, and more under plugins/generic-oauth/providers/ — enumerate with ls $(ask src better-auth)/packages/better-auth/src/plugins/generic-oauth/providers.

oauth-proxy

Server: import { oAuthProxy } from "better-auth/plugins/oauth-proxy"

Proxies OAuth callbacks through a stable production URL so preview deployments (Vercel previews, tunnels, etc.) can complete OAuth flows that require a fixed redirect URI. Reads productionURL or falls back to BETTER_AUTH_URL.

oidc-provider

Server: import { oidcProvider } from "better-auth/plugins/oidc-provider"

Turns better-auth into an OIDC provider (the app hands out tokens to other apps). The inverse of social-providers.

Sessions / tokens

jwt

Server: import { jwt } from "better-auth/plugins/jwt"

Issues signed JWTs alongside the session cookie — useful when other services need to verify sessions without a round-trip.

bearer

Server: import { bearer } from "better-auth/plugins/bearer"

Accepts Authorization: Bearer <token> in addition to cookies. Wire it up for API clients and mobile apps that can't carry cookies.

multi-session

Server: import { multiSession } from "better-auth/plugins/multi-session" Client: import { multiSessionClient } from "better-auth/client/plugins"

Lets a browser keep several concurrent sessions (switch between accounts without signing out).

custom-session

Server: import { customSession } from "better-auth/plugins/custom-session" Client: import { customSessionClient } from "better-auth/client/plugins"

Extend the shape returned by useSession() / getSession() — commonly used to embed the current organization on the session object.

one-time-token

Server: import { oneTimeToken } from "better-auth/plugins/one-time-token" Client: import { oneTimeTokenClient } from "better-auth/client/plugins"

Short-lived single-use tokens (e.g. for invite links or password-less device linking).

device-authorization

Server: import { deviceAuthorization } from "better-auth/plugins/device-authorization" Client: import { deviceAuthorizationClient } from "better-auth/client/plugins"

RFC 8628 device flow — pair a TV / CLI with a browser session.

last-login-method

Server: import { lastLoginMethod } from "better-auth/plugins/last-login-method" Client: import { lastLoginMethodClient } from "better-auth/client/plugins"

Remembers the last auth method per user and exposes it so the UI can highlight it on the sign-in form.

Admin / governance

admin

Server: import { admin } from "better-auth/plugins/admin" Client: import { adminClient } from "better-auth/client/plugins"

Role-based user management: list, ban, impersonate, set role. Pair with access for fine-grained statements.

access

import { createAccessControl, role } from "better-auth/plugins/access"

Not a plugin itself — the access-control primitive used by organization and admin to define role statements (resource × action).

additional-fields

Client-only type helper: import { inferAdditionalFields } from "better-auth/client/plugins"

Propagates extra columns added to the user / session / account tables through the client SDK's types.

haveibeenpwned

Server: import { haveIBeenPwned } from "better-auth/plugins/haveibeenpwned"

Rejects sign-ups / password changes when the password appears in the HIBP k-anonymity API.

captcha

Server: import { captcha } from "better-auth/plugins/captcha"

Gates sensitive endpoints behind Turnstile / hCaptcha / reCAPTCHA / Arkose verification.

Tooling

open-api

Server: import { openAPI } from "better-auth/plugins/open-api"

Exposes an OpenAPI 3 schema for every mounted endpoint (including plugin endpoints) — useful for client-SDK codegen.

mcp

Server: import { mcp } from "better-auth/plugins/mcp"

Model Context Protocol integration — lets an MCP client authenticate against better-auth. Ships MCP-specific adapters: mcpAuthHono, mcpAuthOfficial, mcpAuthMcpUse.

Decision matrix

User-visible needPick
Teams, orgs, workspacesorganization (+ customSession to surface active org)
TOTP / backup codestwo-factor
Passkeys / WebAuthn@better-auth/passkey
Email magic linkmagic-link
Email or SMS OTPemail-otp, phone-number
Remember Ethereum walletsiwe
Admin panel for user managementadmin (+ access)
API clients / mobile (no cookies)bearer
Preview deploys / tunnels break OAuthoauth-proxy
App acts as IdPoidc-provider
Other services need signed claimsjwt
User switches between accountsmulti-session
Pwned-password blocklisthaveibeenpwned
Bot protection on sensitive endpointscaptcha
Auto-generated SDK / docsopen-api

Schema impact

Most plugins add columns or tables. After enabling one, regenerate the schema:

npx auth generate    # prints schema diff / writes files
npx auth migrate     # applies (Kysely built-in only)

Forgetting this step is the top cause of no such column / invalid input syntax errors at runtime. See references/common-errors.md ("schema drift").

README.md

tile.json