docs/content/blogs/1-3.mdx
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 [email protected]
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;
},
}),
],
});
Both OIDC and MCP plugins are production‑ready.
✅ Features:
👉 Read OIDC docs 👉 Read MCP docs
import { mcp } from "better-auth/plugins";
export const auth = betterAuth({
plugins: [
mcp({
loginPage: "/login",
}),
],
});
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({
// ...
}),
],
});
Native support for Sign‑In with Ethereum.
import { siwe } from "better-auth/plugins";
export const auth = betterAuth({
plugins: [
siwe(),
],
});
We’ve added providers for Notion, Slack, Linear, and Faceit.
import { betterAuth } from "better-auth";
export const auth = betterAuth({
socialProviders: {
notion: { /* ... */ },
slack: { /* ... */ },
linear: { /* ... */ },
faceit: { /* ... */ },
},
});
Utilities for handling cookies in SvelteKit server actions.
<Callout type="warn"> Breaking change: `building` and `getRequestEvent` must now be passed in as props. </Callout>import { betterAuth } from "better-auth";
import { sveltekitCookies } from "better-auth/svelte-kit";
import { getRequestEvent } from "$app/server";
export const auth = betterAuth({
plugins: [sveltekitCookies(getRequestEvent)],
});
export const auth = betterAuth({
emailVerification: {
sendOnSignIn: true, // sends a verification email on sign‑in if the user isn’t verified
},
});
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 })], // [!code highlight]
});
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 userexport const auth = betterAuth({
plugins: [
genericOAuth({
// ...
}),
],
});
requireName option for key creationverifyKey now supports async functionscreateSchemainferAuth utility to infer types from the clientauth and authClient examplesrememberMe support in signUpafterEmailVerification hookfreshAge and custom errorURL respected properlyrefresh_token_expires_inExpo: Fixed type path import
SSO: Fixed SAML redirection & type checks
Dropbox: Token access type support
Stripe:
Admin:
ctx in hookscallbackURL in signInUsernamenull type in /get-session responseonSuccess hook now worksorigin-check: Wildcard trusted origins supportedcreate-adapteruseNumberIdserial as PK if useNumberId is enabledonEmailVerification not firingoffline_access no longer requires prompt=consentA lot of refinements to make everything smoother, faster, and more reliable. 👉 Check the full changelog