Better Auth 1.3 Release
We're excited to announce the release of Better Auth 1.3. This release includes a lot of new features and improvements.
To upgrade, run:
npm install better-auth@1.3🚀 Highlights
SSO Plugin
The SSO plugin has been moved to its own package and now supports both OIDC and SAML 2.0.
import { betterAuth } from "better-auth";
import { sso } from "@better-auth/sso";
export const auth = betterAuth({
  plugins: [
    sso({
      oidc: {
        clientId: process.env.OIDC_CLIENT_ID!,
        clientSecret: process.env.OIDC_CLIENT_SECRET!,
      },
      saml: {
        entryPoint: "https://example.com/saml",
        issuer: "better-auth-example",
        certificate: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
      },
      providersLimit: async (user) => {
        const plan = await getUserPlan(user);
        return plan.name === "pro" ? 10 : 1;
      },
    }),
  ],
});OIDC & MCP Plugins – Now Stable
Both OIDC and MCP plugins are production‑ready.
✅ Features:
- Refresh token support in discovery & token endpoints
 - JWKs and PKCE for public clients
 - Trusted clients
 - Encrypted & hashed client secrets
 
👉 Read OIDC docs 👉 Read MCP docs
import { mcp } from "better-auth/plugins";
export const auth = betterAuth({
  plugins: [
    mcp({
      loginPage: "/login",
    }),
  ],
});Stripe Plugin is now production ready
The Stripe plugin is now stable and usage based pricing is coming very soon.
import { betterAuth } from "better-auth";
import { stripe } from "@better-auth/stripe";
export const auth = betterAuth({
  plugins: [
    stripe({
      // ...
    }),
  ],
});SIWE Plugin
Native support for Sign‑In with Ethereum.
import { siwe } from "better-auth/plugins";
export const auth = betterAuth({
  plugins: [
    siwe(),
  ],
});New Social Providers
We’ve added providers for Notion, Slack, Linear, and Faceit.
import { betterAuth } from "better-auth";
export const auth = betterAuth({
  socialProviders: {
    notion: { /* ... */ },
    slack: { /* ... */ },
    linear: { /* ... */ },
    faceit: { /* ... */ },
  },
});SvelteKit Cookie Helper Plugin
Utilities for handling cookies in SvelteKit server actions.
Breaking change: building and getRequestEvent must now be passed in as props.
import { betterAuth } from "better-auth";
import { sveltekitCookies } from "better-auth/svelte-kit";
import { getRequestEvent } from "$app/server";
export const auth = betterAuth({
  plugins: [sveltekitCookies(getRequestEvent)],
});Email Verification on Sign‑In
export const auth = betterAuth({
  emailVerification: {
    sendOnSignIn: true, // sends a verification email on sign‑in if the user isn’t verified
  },
});Multi‑Team Support
The organization plugin now supports members belonging to multiple teams.
Breaking change:
teamId has been removed from the member table. A new teamMembers table is required.
export const auth = betterAuth({
  plugins: [
    organization({
      // ...
    }),
  ],
});import { createAuthClient } from "better-auth/client";
import { organizationClient } from "better-auth/client/plugins";
import { auth } from "./auth";
export const authClient = createAuthClient({
  // pass your auth instance to infer additional fields
  plugins: [organizationClient({ $inferAuth: {} as typeof auth })], 
});Additional Organization Fields
Add custom fields to organization, member, and invitation models.
export const auth = betterAuth({
  plugins: [
    organization({
      schema: {
        organization: { additionalFields: { /* ... */ } },
        member: { additionalFields: { /* ... */ } },
        invitation: { additionalFields: { /* ... */ } },
      },
    }),
  ],
});Other new options:
maximumMembersPerTeam– set team member limitslistUserInvitations– list all invitations for a user
Generic OAuth Improvements
- Added support for extra token URL params
 - OAuth token encryption options
 
export const auth = betterAuth({
  plugins: [
    genericOAuth({
      // ...
    }),
  ],
});API Keys
requireNameoption for key creationverifyKeynow supports async functions
Username
- Availability checks
 - Custom normalization
 
✨ More Features
- Migrated to Zod 4 for better type safety and performance
 - CLI supports custom adapter 
createSchema inferAuthutility to infer types from the client- Improved docs with 
authandauthClientexamples rememberMesupport insignUpafterEmailVerificationhookfreshAgeand customerrorURLrespected properly- OAuth2 tokens now include 
refresh_token_expires_in 
🐛 Bug Fixes & Improvements
Plugins
- 
Expo: Fixed type path import
 - 
SSO: Fixed SAML redirection & type checks
 - 
Dropbox: Token access type support
 - 
Stripe:
- Prevent duplicate customers
 - Allow upgrading incomplete subscriptions
 
 - 
Admin:
- Fixed missing 
ctxin hooks - Proper error when removing invalid user IDs
 
 - Fixed missing 
 
OAuth & Providers
- Fixed duplicate OAuth registration
 - Improved Google/Microsoft scope handling
 - Fixed malformed error URLs in generic OAuth
 - Facebook: Better detection for limited token JWT
 - Twitter: Improved email verification logic
 
Core Authentication
- Exclude current user from username uniqueness check
 - Support 
callbackURLinsignInUsername - Allow account linking without email
 - Fixed missing 
nulltype in/get-sessionresponse - Global 
onSuccesshook now works - JWT: Alternate algorithms supported in JWKS
 origin-check: Wildcard trusted origins supported
CLI, DB, and Adapters
- CLI: Improved Drizzle schema formatting
 - MongoAdapter: Works with 
create-adapter - Schema generation respects 
useNumberId - Postgres: Better varchar normalization and type comparison
 - Drizzle CLI: Uses 
serialas PK ifuseNumberIdis enabled 
Email & OTP
- OTPs now encrypted
 - Fixed 
onEmailVerificationnot firing - Proper error when sign‑up is disabled
 - Phone number: Reset clears verification values
 
Two-Factor Auth
- Default OTP period fix
 - URI generation doesn’t require enabling 2FA
 - Fixed OTP URI separator mismatch
 
Miscellaneous
- Delete organization if member not found
 - Correct error codes for API key rate limits
 - Additional fields now show in OpenAPI
 - Fixed FK constraint generation for MySQL
 - Various improvements to account linking
 - OIDC 
offline_accessno longer requiresprompt=consent - Fixed malformed base64 encoding for token validation
 
A lot of refinements to make everything smoother, faster, and more reliable. 👉 Check the full changelog