new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Better Auth · all subjects

better auth/examples

99 notes in this subject, read out of this brain and free to use. This is page 1 of 2.

Astro example tech stack

The Better Auth Astro example uses Solid for building components.

How to run the Astro example

To run the Astro example: (1) Clone the code sandbox or repository and open it in a code editor, (2) Create a .env file with GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and BETTER_AUTH_SECRET variables, (3) Run pnpm install and pnpm run dev, (4) Open a browser and navigate to http://localhost:3000. The Google sign-in configuration can be removed from auth.ts if not needed.

Astro example environment variables

The Astro example requires three environment variables: GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and BETTER_AUTH_SECRET. These can be obtained from the Google Developer Console.

Astro example features overview

The Better Auth Astro example implements the following features: Email & Password authentication, Social Sign-in with Google, Passkeys, Email Verification, Password Reset, Two Factor Authentication, Profile Update, and Session Management.

Next.js example features

The Better Auth Next.js example demonstrates the following features: Email & Password authentication, Social Sign-in, Passkeys, Email Verification, Password Reset, Two Factor Authentication, Profile Update, Session Management, Organization, Members and Roles.

Next.js example setup steps

To run the Better Auth Next.js example: (1) Clone the code sandbox or repository and open in a code editor, (2) Move .env.example to .env and provide necessary variables, (3) Run `pnpm install` followed by `pnpm dev`, (4) Open a browser and navigate to http://localhost:3000.

Next.js example SSO login with DummyIDP

The Next.js example includes an SSO Login Example that uses DummyIDP. To test it, initiate the login from the DummyIDP login page at https://dummyidp.com/apps/app_01k16v4vb5yytywqjjvv2b3435/login, click "Proceed", and it will redirect to the user's dashboard.

Next.js example SCIM sync with DummyIDP

The Next.js example includes a SCIM Sync Example that uses DummyIDP. Test it by going to the IDP dashboard at https://dummyidp.com/apps/app_01k16v4vb5yytywqjjvv2b3435, add, update or remove users, then check the admin page or database to observe the synchronization work.

Nuxt example features

The Nuxt example for Better Auth implements Email & Password authentication and Social Sign-in with Google.

Nuxt example repository location

The Nuxt example code is available at better-auth/examples/tree/main/nuxt-example.

Nuxt example setup instructions

To run the Nuxt example: Clone the code sandbox or repository and open it in your code editor. Move .env.example to .env and provide necessary variables. Run pnpm install followed by pnpm dev. Open the browser and navigate to http://localhost:3000.

React Router v7 example features

The Better Auth React Router v7 example implements Email & Password authentication, Social Sign-in with Google, Passkeys, Email Verification, Password Reset, Two Factor Authentication, Profile Update, and Session Management.

React Router v7 example repository location

The React Router v7 example code is available at better-auth/examples/tree/main/react-router-example on GitHub.

React Router v7 example setup instructions

To run the React Router v7 example: clone the code sandbox or repo and open in a code editor, provide a .env file by copying the .env.example file and adding variables, run `pnpm install` followed by `pnpm run dev`, then open a browser and navigate to http://localhost:3000.

SvelteKit example features

The Better Auth SvelteKit example implements the following features: Email & Password authentication, Social Sign-in with Google, Passkeys, Email Verification, Password Reset, Two Factor Authentication, Profile Update, and Session Management.

SvelteKit example repository location

The SvelteKit example code is available at better-auth/examples/tree/main/svelte-kit-example in the Better Auth GitHub repository.

How to run SvelteKit example

To run the Better Auth SvelteKit example: (1) Clone the code sandbox or repository and open it in a code editor, (2) Rename .env.example to .env and provide necessary variables, (3) Run pnpm install followed by pnpm dev, (4) Open a browser and navigate to http://localhost:3000.

Auth0 password hash migration supports bcrypt

The migratePassword function in the Auth0 migration script handles bcrypt password hashes starting with '$2a$' or '$2b$'. It also supports custom password hashes with custom algorithm, hash value, encoding, digest, key, and salt properties. For non-bcrypt algorithms, custom hash data is serialized as JSON.

Auth0 migration role mapping customization

The mapAuth0RoleToBetterAuthRole function maps Auth0 roles to Better Auth format. If auth0Roles is a string, return as-is. If an array, join with commas. Customize this function based on your specific Auth0 roles and Better Auth role requirements.

Auth0 migration verification checklist

After running the migration, verify: (1) all users have been properly migrated, (2) social connections are working, (3) password-based authentication is working, (4) two-factor authentication settings are preserved if enabled, (5) user roles and permissions are correctly mapped.

Generate or migrate schema after Auth0 migration setup

After configuring Better Auth for Auth0 migration, generate the database schema. Use 'npx auth generate' for custom database adapters or 'npx auth migrate' for the default adapter.

Better Auth middleware for Auth0 migration

Replace Auth0 middleware with Better Auth middleware using getSessionCookie from 'better-auth/cookies'. Example: extract sessionCookie from NextRequest, redirect authenticated users away from /login and /signup, redirect unauthenticated users away from /dashboard. Configure matcher for routes to protect.

Auth0 migration handles pagination with checkpoint and offset

The migration script uses pagination to handle large user counts. It uses .list() with take parameter for checkpoint pagination and per_page/page parameters for offset pagination. The script checks hasNextPage() and calls getNextPage() to fetch all results. Pagination values should be adjusted based on rate limits.

Auth0 migration timestamp conversion handles edge cases

The safeDateConversion function converts Auth0 timestamps (string or numeric) to JavaScript Date objects. It detects if the timestamp is in seconds (< 1e12) and converts to milliseconds. It warns and returns current date for invalid timestamps or dates with years outside 2000-2100 range.

Auth0 migration script environment variables

The migration script requires three Auth0 environment variables: AUTH0_DOMAIN, AUTH0_CLIENT_ID, and AUTH0_SECRET. These are used to instantiate the ManagementClient for fetching users, organizations, members, and roles from Auth0.

Auth0 migration setup requires Better Auth installation

Before starting the Auth0 migration process, set up Better Auth in your project by following the installation guide. Then connect to your database (e.g., PostgreSQL with the pg package) by passing a Pool instance to betterAuth's database option.

Auth0 user base data mapping to Better Auth

User data migrated from Auth0 includes: id, email, emailVerified, name (from name or nickname), image (from picture), createdAt, updatedAt. When admin plugin is enabled, adds banned (from blocked) and role fields. When username plugin is enabled, adds username (from username or nickname). All fields are mapped with null/false defaults where needed.

Auth0 organizations migration includes members and roles

The migrateOrganizations function fetches all Auth0 organizations and their members. For each member, it retrieves their roles within the organization. It creates organization records with id, display_name as name, slug, branding logo_url, metadata, and createdAt. It creates member records mapping organization and user IDs with their roles.

Auth0 OAuth accounts migration maps providers

The migrateOAuthAccounts function migrates Auth0 identities as account records. Provider ID is extracted from identity.provider: if 'auth0', it maps to 'credential'; otherwise it takes the first part before the hyphen (e.g., 'google-oauth2' becomes 'google'). It migrates accessToken, tokenType, refreshToken, scope, idToken, and expiration times.

Auth0 MFA factors migration generates backup codes

The migrateMFAFactors function migrates TOTP secrets from Auth0 MFA factors. For each factor with a TOTP secret, it creates a twoFactor record in Better Auth, generating 10 backup codes of format 'XXXXX-XXXXX'. Backup codes are encrypted using symmetricEncrypt with the TOTP secret as the key.

Auth0 migration invalidates active sessions

Migrating from Auth0 to Better Auth will invalidate all active sessions. When the Organization plugin is enabled, the migration script will attempt a best-effort migration of Auth0 Organizations, their members, and per-member roles. Invitations and enabled-connection configuration are not migrated and must be reconfigured manually.

Auth0 migration script uses ManagementClient

The migration script instantiates auth0 ManagementClient with domain, clientId, and clientSecret from environment variables. Example: new ManagementClient({ domain: process.env.AUTH0_DOMAIN!, clientId: process.env.AUTH0_CLIENT_ID!, clientSecret: process.env.AUTH0_SECRET! })

Auth0 bulk user export alternative to Management API

Instead of using the Management API, you can use Auth0's bulk user export functionality and pass the exported JSON data directly to the auth0Users array. This is especially useful if you need to migrate password hashes and complete user data, which are not available through the Management API. Password hashes export is only available for Auth0 Enterprise users; Free plan users cannot export password hashes.

Browser extension manifest host permissions

In package.json, add a manifest field with host_permissions array containing the URL of your Better Auth backend. Example: "manifest": { "host_permissions": ["https://URL_TO_YOUR_BACKEND"] }. Localhost URLs like http://localhost:3000 are supported.

Browser extension setup with Plasmo

To initialize a new Plasmo project for a browser extension with Better Auth, run: pnpm create plasmo --with-tailwindcss --with-src. Then install better-auth with: pnpm add better-auth. Start the development server with: pnpm dev.

tsconfig.json configuration for Plasmo extension

Configure tsconfig.json with strict mode enabled and import alias set to @ pointing to the src directory. The configuration should include: compilerOptions with paths object containing @/_ mapped to ./src/_, strict set to true, and baseUrl set to ..

Build browser extension for production

To create a production build of the Plasmo extension, run: pnpm build. This generates the extension bundle in build/chrome-mv3-prod directory (or build/chrome-mv3-dev for development).

Load unpacked extension in Chrome

To load the extension during development: go to chrome://extensions, enable developer mode, click 'Load Unpacked', and navigate to the build/chrome-mv3-dev (or build/chrome-mv3-prod) directory. Access the extension via the puzzle piece icon on the Chrome toolbar.

Find Chrome extension ID

Navigate to chrome://extensions to view your extension details and find its unique extension ID. This ID is needed to configure the extension URL in the format chrome-extension://YOUR_EXTENSION_ID.

Browser extension prerequisite

The Plasmo framework does not provide a backend for browser extensions. A Better Auth backend must already be set up before creating the browser extension to connect to it.

Migration pre-flight checks and safety practices

Before running a Clerk to Better Auth migration, test in a development environment first, monitor the migration process for errors, verify migrated data in Better Auth before proceeding, and keep Clerk installed and configured until migration is complete.

Check if plugins are enabled during migration

During migration, check which plugins are enabled by accessing ctx.options.plugins and finding plugins by their id: 'admin', 'two-factor', 'username', 'phone-number'. Only include corresponding fields in migrated user data if the plugin is enabled.

Two-factor TOTP data migration from Clerk

When migrating two-factor data from Clerk to Better Auth, create twoFactor records in the adapter with userId, secret (from totp_secret), and backupCodes (generated using symmetricEncrypt with the secret as key and 10 backup codes of format 'XXXXX-XXXXX').

Clerk account model migration for social and password

When migrating Clerk accounts to Better Auth account model, for credential provider (password accounts) create account with providerId='credential', accountId from provider_user_id, and password field containing password_digest. For OAuth providers, create account with providerId=(provider name without 'oauth_' prefix), accountId from provider_user_id. Include scope and timestamps (createdAt, updatedAt) for all accounts.

Clerk migration user model fields mapping

When migrating Clerk users to Better Auth, map the following fields: id → id, primary_email_address → email, verified_email_addresses.length > 0 → emailVerified, first_name + last_name → name, image_url (from API) → image, Clerk created_at → createdAt, Clerk updated_at → updatedAt. For admin plugin: banned → banned, lockout_expires_in_seconds → banExpires, role set to 'user'. For two-factor plugin: two_factor_enabled → twoFactorEnabled. For username plugin: username → username. For phone-number plugin: primary_phone_number → phoneNumber, verified_phone_numbers.length > 0 → phoneNumberVerified.

Clerk API endpoint for fetching users during migration

Clerk users can be fetched via the API endpoint `https://api.clerk.com/v1/users?offset={offset}&limit={limit}` with Authorization header containing Bearer token of CLERK_SECRET_KEY. The endpoint supports pagination with offset and limit parameters (max 500 per request).

Clerk migration invalidates all active sessions

Migrating from Clerk to Better Auth will invalidate all active sessions. The migration guide does not currently show how to migrate Organization data, but it should be possible with additional steps using the Organization Plugin.

Clerk uses bcrypt, Better Auth uses scrypt by default

Clerk uses bcrypt to hash passwords, while Better Auth uses scrypt by default. To ensure migrated users can sign in with their existing passwords, Better Auth must be configured to use bcrypt for password verification by providing custom hash and verify functions.

Clerk CSV export columns for user migration

Clerk CSV export includes the following columns: id, first_name, last_name, username, primary_email_address, primary_phone_number, verified_email_addresses, unverified_email_addresses, verified_phone_numbers, unverified_phone_numbers, totp_secret, password_digest, and password_hasher.

Export users from Clerk dashboard

To export users from Clerk, go to the Clerk dashboard and export the users. This downloads a CSV file with user data that should be saved as `exported_users.csv` in the root of the project.

Background tasks example with Vercel waitUntil

The advanced.backgroundTasks handler can use Vercel's waitUntil function. In a hook's after middleware, call ctx.context.runInBackground() to defer work like logging sign-ups.

Preload Convex queries with Better Auth in SSR

Use preloadAuthQuery in server components to preload data and usePreloadedAuthQuery in client components to render it. In server component: import { api } from '@/convex/_generated/api'; import { preloadAuthQuery } from '@/lib/auth-server'; const Page = async () => { const preloadedUserQuery = await preloadAuthQuery(api.auth.getCurrentUser); return <Header preloadedUserQuery={preloadedUserQuery} />; }; In client component: 'use client'; import { usePreloadedAuthQuery } from '@convex-dev/better-auth/nextjs/client'; import type { Preloaded } from 'convex/react'; const Header = ({ preloadedUserQuery }: { preloadedUserQuery: Preloaded<typeof api.auth.getCurrentUser>; }) => { const user = usePreloadedAuthQuery(preloadedUserQuery); return user ? ... : ...; };

Use Convex server helpers for authentication

Use server helpers from auth-server in server components to check authentication. Example in `app/protected/page.tsx`: import { isAuthenticated } from '@/lib/auth-server'; const Page = async () => { const hasToken = await isAuthenticated(); if (!hasToken) return <div>Unauthorized</div>; return <div><p>Hello</p></div>; }; export default Page;

Use Convex React hooks with Better Auth

In client components, use Convex React hooks like useQuery to call Convex functions. Example in `app/dashboard/page.tsx`: 'use client'; import { useQuery } from 'convex/react'; import { api } from '@/convex/_generated/api'; const Page = () => { const user = useQuery(api.auth.getCurrentUser); if (user === undefined) return <div>Loading...</div>; if (user === null) return <div>Unauthorized</div>; return <div><pre>{JSON.stringify(user, null, 2)}</pre></div>; }; export default Page;

Convex functions for Better Auth

Create Convex functions in the `convex/` directory (like `convex/auth.ts`) to run Better Auth methods that normally run on the server. Functions can be called from the client via hooks like useMutation or from server functions using auth-server utilities like fetchAuthMutation. Example: export const getCurrentUser = query({ args: {}, handler: async (ctx) => { const identity = await ctx.auth.getUserIdentity(); return identity; }, });

Better Auth with Convex client usage example

Use the authClient in client components to call signIn.social. Example in `app/sign-in/page.tsx`: 'use client'; import { Button } from '@/components/ui/button'; import { authClient } from '@/lib/auth-client'; const Page = () => { return <div className='flex flex-col items-center justify-center h-screen'><Button onClick={async () => { await authClient.signIn.social({ provider: 'github', callbackURL: '/dashboard', }); }}>Sign in with GitHub</Button></div>; }; export default Page;

Example: Electron client plugin setup with conf storage

```ts title="electron/lib/auth-client.ts" import { storage } from "@better-auth/electron/storage"; electronClient({ storage: storage(), }); ```

Electron client plugin userImageProxy enabled option

```ts title="electron/auth-client.ts" electronClient({ userImageProxy: { enabled: true, maxSize: 1024 * 1024 * 5, }, }); ```

Electron client plugin userImageProxy disabled option

```ts title="electron/auth-client.ts" electronClient({ userImageProxy: { enabled: false, }, }); ```

Electron client plugin disableCache option

```ts title="electron/auth-client.ts" electronClient({ disableCache: true, }); ```

Give your agent this brain