{"id":16761,"library":"better-auth-custom-credentials","title":"Better Auth Custom Credentials Plugin","description":"This package provides a plugin for the `better-auth` library, enabling highly customizable credentials-based authentication. It allows developers to integrate `better-auth` with virtually any backend authentication system, such as Rails, Django, custom APIs, or LDAP, while leveraging `better-auth`'s existing session management infrastructure. Currently at version 0.1.8, the library is in active development, meaning minor versions may introduce breaking changes to its API. Key differentiators include the ability to define flexible input schemas using Zod for robust validation, store arbitrary custom data (like JWTs or permissions) directly within `better-auth` sessions, configure auto sign-up features, and set custom session expiry per authentication method. It offers a comprehensive solution for adapting diverse authentication logic to the `better-auth` ecosystem.","status":"active","version":"0.1.8","language":"javascript","source_language":"en","source_url":"https://github.com/Pradumn27/better-auth-custom-credentials","tags":["javascript","better-auth","authentication","credentials","plugin","auth","nextauth","typescript"],"install":[{"cmd":"npm install better-auth-custom-credentials","lang":"bash","label":"npm"},{"cmd":"yarn add better-auth-custom-credentials","lang":"bash","label":"yarn"},{"cmd":"pnpm add better-auth-custom-credentials","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core authentication library that this plugin extends.","package":"better-auth","optional":false},{"reason":"Used for defining and validating input schemas for the custom credentials.","package":"zod","optional":false}],"imports":[{"note":"This is the main server-side plugin for Better Auth, primarily used in ESM contexts.","wrong":"const credentialsPlugin = require('better-auth-custom-credentials');","symbol":"credentialsPlugin","correct":"import { credentialsPlugin } from 'better-auth-custom-credentials';"},{"note":"Used client-side, typically with React/Next.js, to extend the `better-auth` client with credentials methods. Requires `createAuthClient` from `better-auth/react`.","wrong":"const extendAuthClientWithCredentials = require('better-auth-custom-credentials').extendAuthClientWithCredentials;","symbol":"extendAuthClientWithCredentials","correct":"import { extendAuthClientWithCredentials } from 'better-auth-custom-credentials';"},{"note":"Zod is a peer dependency and is essential for defining the input schema for the credentials plugin.","symbol":"z","correct":"import { z } from 'zod';"}],"quickstart":{"code":"import { createAuthClient } from 'better-auth/react';\nimport { extendAuthClientWithCredentials } from 'better-auth-custom-credentials';\n\n// Create a basic Better Auth client, ensuring credentials are included for session management.\n// This client will interact with your server-side Better Auth setup.\nexport const authClient = extendAuthClientWithCredentials(\n  createAuthClient({\n    fetch: (url, init) => {\n      return fetch(url, {\n        ...init,\n        credentials: 'include', // Important: Ensures cookies are sent with requests\n        cache: 'no-store',\n      });\n    },\n  })\n);\n\nasync function authenticateAndGetSession() {\n  console.log('Attempting to sign in with credentials...');\n  // Sign in using the credentials method. The input object must match the server-side Zod schema.\n  const result = await authClient.signIn.credentials({\n    email: 'user@example.com',\n    otp: '123456',\n    rememberMe: true,\n  });\n\n  if (result.ok) {\n    console.log('Sign in successful!');\n    // Retrieve the session data after successful authentication.\n    const { data: session } = await authClient.getSession();\n    const jwt = session?.data?.jwt;\n    const permissions = session?.data?.permissions;\n\n    console.log('Session Data:', session);\n    console.log('JWT:', jwt);\n    console.log('Permissions:', permissions);\n  } else {\n    console.error('Sign in failed:', result.reason);\n  }\n}\n\n// Example call (in a real app, this would be triggered by a form submission or similar event)\n// authenticateAndGetSession();","lang":"typescript","description":"Demonstrates client-side setup for `better-auth-custom-credentials`, including extending the auth client, signing in with custom credentials, and retrieving session data."},"warnings":[{"fix":"Review the official GitHub repository for the latest API documentation and migration guides when updating versions. Pin exact versions in `package.json` to prevent unexpected breaks.","message":"As a pre-1.0 package (version 0.1.8), the API is subject to frequent and significant breaking changes between minor versions. Always consult the latest README and changelog before upgrading.","severity":"breaking","affected_versions":">=0.1.0"},{"fix":"Ensure your `verify` implementation consistently returns an object with an `ok` boolean, an optional `reason` (for failures), and `user` and `meta` (for success) to be picked up by Better Auth's session management.","message":"The `verify` function within `credentialsPlugin` must strictly return an object conforming to `{ ok: boolean; reason?: string; user?: User; meta?: Record<string, any> }` on success or failure. An incorrect return type can lead to authentication failures or incomplete session data.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Modify your `createAuthClient` configuration to always pass `{ credentials: 'include' }` in the `fetch` options: `createAuthClient({ fetch: (url, init) => fetch(url, { ...init, credentials: 'include' }) })`.","message":"When using `createAuthClient` on the client-side, it is crucial to include `credentials: 'include'` in your `fetch` configuration. Omitting this will prevent cookies (like session tokens) from being sent with requests, leading to unauthenticated requests or session management issues.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Always provide a comprehensive `z.object()` schema to the `inputSchema` property of `credentialsPlugin` to define and validate all expected input fields from the client-side form.","message":"Forgetting to define a robust `inputSchema` using Zod within the `credentialsPlugin` configuration can lead to insecure or unexpected authentication behavior, as input validation will be absent or incomplete.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure you are using ECMAScript Modules (ESM) import syntax: `import { credentialsPlugin } from 'better-auth-custom-credentials';`.","cause":"Attempting to import `credentialsPlugin` using CommonJS `require()` syntax or incorrect named import from an ESM-only package.","error":"TypeError: credentialsPlugin is not a function"},{"fix":"Review your server-side `inputSchema` and ensure the client-side `signIn.credentials` method is sending an object with the exact keys and types expected by the schema.","cause":"The data sent from the client-side `authClient.signIn.credentials()` call does not conform to the `inputSchema` defined with Zod on the server-side `credentialsPlugin`.","error":"ZodError: Invalid input"},{"fix":"Install the required peer dependencies: `npm install better-auth zod` or `pnpm add better-auth zod`.","cause":"The `better-auth` or `zod` peer dependencies are not installed in your project.","error":"Error: Cannot find module 'better-auth' or 'zod'"},{"fix":"Ensure the `user` object returned from `verify` includes all mandatory fields (e.g., `id`, `email`, `name`) that your `better-auth` configuration expects for a `User`.","cause":"The `user` object returned by the `verify` function does not contain all required properties as defined by your application's `User` type for Better Auth.","error":"Type 'Partial<User>' is not assignable to type 'User'. Property 'id' is missing in type 'Partial<User>' but required in type 'User'."}],"ecosystem":"npm","meta_description":null}