Independent and unofficial. This Python project is inspired by Better Auth and is not affiliated with, maintained by, endorsed by, or sponsored by the Better Auth project or its maintainers.

BETTER-AUTH.

All posts

Better Auth 1.3

SSO with SAML, Multi Team Support, Additional Fields for Organization, Performance and more.

Bereket Engida·@bekacru·Jul 19, 2025

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.

👉 Read the SSO docs

auth.ts
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

auth.ts
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.

👉 Read Stripe docs

auth.ts
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.

👉 Read SIWE docs

auth.ts
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.

auth.ts
import { betterAuth } from "better-auth";

export const auth = betterAuth({
  socialProviders: {
    notion: { /* ... */ },
    slack: { /* ... */ },
    linear: { /* ... */ },
    faceit: { /* ... */ },
  },
});

Utilities for handling cookies in SvelteKit server actions.

Breaking change: building and getRequestEvent must now be passed in as props.

auth.ts
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

auth.ts
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.

auth.ts
export const auth = betterAuth({
  plugins: [
    organization({
      // ...
    }),
  ],
});
auth-client.ts
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.

auth.ts
export const auth = betterAuth({
  plugins: [
    organization({
      schema: {
        organization: { additionalFields: { /* ... */ } },
        member: { additionalFields: { /* ... */ } },
        invitation: { additionalFields: { /* ... */ } },
      },
    }),
  ],
});

Other new options:

  • maximumMembersPerTeam – set team member limits
  • listUserInvitations – list all invitations for a user

Generic OAuth Improvements

  • Added support for extra token URL params
  • OAuth token encryption options
auth.ts
export const auth = betterAuth({
  plugins: [
    genericOAuth({
      // ...
    }),
  ],
});

API Keys

  • requireName option for key creation
  • verifyKey now 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
  • inferAuth utility to infer types from the client
  • Improved docs with auth and authClient examples
  • rememberMe support in signUp
  • afterEmailVerification hook
  • freshAge and custom errorURL respected 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 ctx in hooks
    • Proper error when removing invalid user IDs

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 callbackURL in signInUsername
  • Allow account linking without email
  • Fixed missing null type in /get-session response
  • Global onSuccess hook 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 serial as PK if useNumberId is enabled

Email & OTP

  • OTPs now encrypted
  • Fixed onEmailVerification not 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_access no longer requires prompt=consent
  • Fixed malformed base64 encoding for token validation

A lot of refinements to make everything smoother, faster, and more reliable. 👉 Check the full changelog