Mikro ORM Adapter for Better Auth
This package provides a Mikro ORM adapter for Better Auth, allowing developers to integrate Better Auth's authentication functionalities with a MikroORM-managed database. The current stable version is `0.5.0`, and the project demonstrates a relatively active release cadence with frequent minor and patch updates based on the provided changelog. A key differentiator is its specific integration with MikroORM, serving as a bridge for authentication operations. It's crucial to note that this adapter does not handle database schema management directly; users are expected to define and manage their core Better Auth and plugin-specific schemas within MikroORM independently. This also means it cannot be used with `@better-auth/cli` for schema generation or migrations, distinguishing it from adapters that abstract schema concerns.
Common errors
-
Error: Cannot find module 'better-auth-mikro-orm' or its corresponding type declarations.
cause Attempting to use CommonJS `require()` syntax in an ESM project, or incorrect import path/module resolution issues.fixEnsure you are using `import { mikroOrmAdapter } from 'better-auth-mikro-orm';` for ESM. Verify `"type": "module"` is set in your `package.json` if using ESM. Check that the package is correctly installed. -
TypeError: Cannot read properties of undefined (reading 'em') or 'em' is null.
cause The MikroORM instance passed to `mikroOrmAdapter` was not fully initialized, or `MikroORM.init` failed, resulting in an undefined or null `EntityManager` (`orm.em`).fixVerify that `MikroORM.init()` or `MikroORM.initSync()` successfully completes and returns a valid `MikroORM` instance before passing it to `mikroOrmAdapter`. Await the initialization call if it's asynchronous. -
Better Auth Error: duplicate key value violates unique constraint "users_id_pkey"
cause This typically occurs when `advanced.database.generateId: false` was not set in the Better Auth configuration, leading to Better Auth attempting to generate IDs that conflict with MikroORM's auto-generated primary keys.fixAdd or verify `advanced: { database: { generateId: false } }` in your `betterAuth` configuration. Ensure your MikroORM entities have appropriate primary key strategies (e.g., `uuid` or `serial`).
Warnings
- breaking In `v0.4.2`, the `updateMany` and `deleteMany` methods were changed to use MikroORM's `nativeDelete` and `nativeUpdate` methods. This change prevents the MikroORM Identity Map from being updated for affected entities. While `deleteMany` was later corrected in `v0.4.1` to use `remove` (restoring Identity Map updates for deletions), `updateMany` continues to bypass the Identity Map in `v0.4.x` and potentially later versions.
- gotcha This MikroORM adapter explicitly does not manage database schemas. You cannot use the `@better-auth/cli` for schema generation or migrations with this package. Developers must define and manage all necessary Better Auth and plugin-specific entities and migrations using MikroORM's native schema management tools.
- gotcha When integrating Better Auth with MikroORM, you must disable Better Auth's built-in ID generator by setting `advanced.database.generateId: false` in the Better Auth configuration. MikroORM is expected to manage ID generation for your entities.
- gotcha The adapter expects an initialized `MikroORM` instance. Ensure that `MikroORM.init` or `MikroORM.initSync` has been called and the resulting `orm` object is passed to `mikroOrmAdapter`. The `EntityManager` (`orm.em`) must be accessible and configured.
Install
-
npm install better-auth-mikro-orm -
yarn add better-auth-mikro-orm -
pnpm add better-auth-mikro-orm
Imports
- mikroOrmAdapter
const mikroOrmAdapter = require('better-auth-mikro-orm');import { mikroOrmAdapter } from 'better-auth-mikro-orm'; - AdapterInstance
import type { AdapterInstance } from 'better-auth-mikro-orm'; - AuthEntity
import type { AuthEntity } from 'better-auth-mikro-orm';
Quickstart
import { mikroOrmAdapter } from "better-auth-mikro-orm";
import { betterAuth } from "better-auth";
import { MikroORM } from "@mikro-orm/core";
// Assume 'orm' is an initialized MikroORM instance
// For demonstration, we'll create a mock, but in a real app, it would be MikroORM.init
const mockEntityManager = {
find: async () => [],
findOne: async () => null,
persistAndFlush: async () => {},
removeAndFlush: async () => {},
nativeInsert: async () => {},
nativeUpdate: async () => {},
nativeDelete: async () => {},
transactional: async (cb: any) => cb(),
getRepository: (entity: any) => ({ /* mock methods */ }),
count: async () => 0
};
const orm = { em: mockEntityManager } as unknown as MikroORM; // Your Mikro ORM instance
export const auth = betterAuth({
database: mikroOrmAdapter(orm),
// Don't forget to disable the ID generator if it is already managed by MikroORM
advanced: {
database: {
generateId: false
}
}
});
console.log("Better Auth instance initialized with MikroORM adapter.");
// You would typically use 'auth' here, e.g., auth.signIn, auth.createUser
// For example, to check if the adapter works:
async function demonstrateUsage() {
// This is a conceptual example, actual usage depends on Better Auth's API
// which would interact with the adapter's methods like find, create, etc.
// Example: Trying to create a user (conceptual, requires Better Auth's specific API)
try {
// This part is highly dependent on Better Auth's actual API for user creation
// and how it interacts with the adapter. This is illustrative.
// const newUser = await auth.createUser({ email: "test@example.com", password: "securepassword" });
// console.log("Attempted to create user via Better Auth with MikroORM adapter.");
console.log("Adapter setup successful. Ready for Better Auth operations.");
} catch (error) {
console.error("Error during conceptual user creation:", error);
}
}
demonstrateUsage();