Registry / auth-security / better-auth-credentials-plugin

better-auth-credentials-plugin

JSON →
library0.5.2jsnpmunverified

The Better Auth Credentials Plugin provides a highly customizable mechanism for authenticating users against external systems like LDAP, custom APIs, or other credential-based services, integrating seamlessly with the Better Auth ecosystem. It is currently at version 0.5.2 and appears to have a relatively active release cadence, with several minor releases in recent months addressing bug fixes and compatibility. Key differentiators include full control over the authentication callback logic, optional auto sign-up, management of account linking and session creation, and flexible route customization with Zod schemas for validation and OpenAPI documentation. It's designed to complement, not replace, Better Auth's native email/password or username flows when integrating with third-party authentication sources. The plugin explicitly supports both server and client-side integration.

npm install better-auth-credentials-plugin
INSTALL
IMPORT
SIG · BETTER-AUTH-CREDEN
B
better-auth-credentials-plugin
auth-securityjavascriptv0.5.2
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

credentials
import { credentials } from 'better-auth-credentials-plugin';
const credentials = require('better-auth-credentials-plugin');
This is the main server-side plugin function for configuring credential authentication. The package is ESM-first, commonjs `require` syntax may not work directly without transpilation or bundler configuration.
credentialsClient
import { credentialsClient } from 'better-auth-credentials-plugin/client';
import { credentialsClient } from 'better-auth-credentials-plugin';
For client-side usage, particularly with bundlers like Webpack or Turbopack, you must use the `/client` subpath import to prevent server-side dependencies from being included in the client bundle. This was addressed in v0.4.0.
defaultCredentialsSchema
import { defaultCredentialsSchema } from 'better-auth-credentials-plugin/client';
Provides a default Zod schema for credentials, often used in conjunction with `credentialsClient` on the frontend.

This quickstart demonstrates the server-side setup for the credentials plugin within a Better Auth instance, showing how to implement a custom authentication callback to verify user credentials against an external API. It also highlights the necessary client-side import pattern.

import { betterAuth } from "better-auth"; import { credentials } from "better-auth-credentials-plugin"; // --- Server-side configuration (e.g., in auth.ts) --- export const auth = betterAuth({ // ... other Better Auth configurations ... // Disable default email and password if this plugin replaces it for a specific flow emailAndPassword: { enabled: false, }, plugins: [ credentials({ autoSignUp: true, // Automatically create a new user if not found async callback(ctx, parsed) { // 'parsed' contains the validated input credentials (e.g., username, password) // Implement your external authentication logic here (e.g., LDAP, external API) const { email, password } = parsed; // Example: Authenticating against a hypothetical external API const externalAuthServiceUrl = process.env.EXTERNAL_AUTH_SERVICE_URL ?? 'http://localhost:4000/login'; const response = await fetch(externalAuthServiceUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password }), }); if (!response.ok) { // Handle authentication failure from the external system const errorData = await response.json().catch(() => ({ message: 'Authentication failed' })); throw new Error(errorData.message || 'Invalid credentials'); } const { token, user: apiUser } = await response.json(); // Return user data, including a unique 'email' field, to Better Auth. // This data will be used to create/update the user and link the account. return { // 'email' is mandatory for Better Auth user linking/creation email: apiUser.email, // Additional fields to store on the user or account (e.g., token, name) name: apiUser.name, externalAuthToken: token, }; }, }), ], }); // --- Client-side usage (e.g., in authClient.ts) --- // Requires 'better-auth/client' and '/client' subpath for credentialsClient // import { createAuthClient } from 'better-auth/client'; // import { credentialsClient } from 'better-auth-credentials-plugin/client'; // const authClient = createAuthClient({ // baseURL: "/api/auth", // plugins: [ // // If you customized the path or schema, you'd pass generic types here // credentialsClient(), // ], // });
Debug
Known issues
breakingThe `internalAdapter` signature within Better Auth changed in v1.4.0. Upgrading to `better-auth-credentials-plugin` v0.4.0 and higher requires `better-auth` >=1.4.0 to maintain compatibility.
fix
Ensure your `better-auth` peer dependency is updated to `^1.5.0` or newer, as specified in the plugin's `peerDependencies`.
affects: >=0.4.0
gotchaWhen using bundlers like Webpack, Turbopack, or Vite, the client-side module `credentialsClient` must be imported via the dedicated subpath `better-auth-credentials-plugin/client`. Failing to do so can result in server-side dependencies being bundled into client code, leading to errors or unnecessarily large bundles.
fix
Change client-side imports from `import { credentialsClient } from 'better-auth-credentials-plugin';` to `import { credentialsClient } from 'better-auth-credentials-plugin/client';`
affects: >=0.4.0
gotchaThe credentials callback *must* return an `email` field as part of the user data. This email is crucial for Better Auth to create or update the user in the database and link the account with the session. If `autoSignUp` is enabled and no `email` is returned, user creation will fail.
fix
Ensure your `callback` function always returns an object containing a unique `email` property (e.g., `{ email: 'user@example.com', ...otherUserData }`).
affects: >=0.1.0
gotchaThis plugin is not intended for re-implementing standard email and password login by storing hashed passwords in your database. Using it this way would lead to redundant database lookups and is less efficient than Better Auth's native `emailAndPassword` or `username` plugins.
fix
For standard password-based authentication, use Better Auth's built-in `emailAndPassword` or `username` plugins. Only use `better-auth-credentials-plugin` for integration with *external* credential systems like LDAP or custom APIs.
affects: >=0.1.0
gotchaWhen integrating with Better Auth's default `emailAndPassword` or `username` flows, accounts created via the credentials plugin will not automatically be able to log in with email/password (as no password is set). To allow users to log in with both methods, configure a custom `providerId` for this plugin and set `linkAccountIfExisting: true`.
fix
Consider setting a unique `providerId` in the plugin configuration (e.g., `credentials({ providerId: 'ldap', ... })`) and enabling `linkAccountIfExisting: true` if you want users to link multiple authentication methods to a single Better Auth account.
affects: >=0.1.0
Errors
Common errors & fixes
TypeError: Cannot read properties of undefined (reading 'internalAdapter')
This typically occurs when `better-auth-credentials-plugin` is used with an older version of `better-auth` that does not match the plugin's expected `internalAdapter` API signature.
fix
Update your `better-auth` package to version `^1.5.0` or higher to match the plugin's requirements. Run `npm install better-auth@latest`.
Error: ZodError: [ { "code": "invalid_type", "expected": "string", "received": "undefined", "path": [ "email" ], "message": "Email is required" } ]
The credentials `callback` did not return a required `email` field, or the `inputSchema` (if custom) was not satisfied by the incoming credentials.
fix
Ensure your `callback` function returns an object with at least a valid `email` property. If using a custom `inputSchema`, verify the incoming `parsed` object from the client matches its requirements.
Module not found: Error: Can't resolve 'better-auth-credentials-plugin'
This error, particularly in a client-side bundle, often means the bundler is trying to import the server-side entrypoint or the subpath import is incorrect for the client.
fix
For client-side code, ensure you are importing from the `/client` subpath: `import { credentialsClient } from 'better-auth-credentials-plugin/client';`. Also, check that `better-auth-credentials-plugin` is correctly installed.
TypeError: require is not a function in ES module scope
Attempting to use CommonJS `require()` syntax in an ESM project, or a bundler configuration issue where `better-auth-credentials-plugin` is treated as CommonJS.
fix
Ensure your project is configured for ESM. Use `import { credentials } from 'better-auth-credentials-plugin';` instead of `const credentials = require('better-auth-credentials-plugin');`. If using a bundler, verify its configuration for resolving ESM packages.
Upgrade
Version history
0.5.2latest on npm
Audit
Dependencies
@standard-schema/specrequiredRequired for defining input schemas for validation and API documentation.
better-authrequiredCore dependency as this is a plugin for Better Auth. Version >=1.5.0 is recommended due to internal API changes.
zodrequiredUsed for schema definition and validation. Supports both v3 and v4, but compatibility with Better Auth version must be considered.
Agent activity
28 hits · last 30 days
node
22
OpenAI (training)
1
Resources