{"id":16712,"library":"better-auth-convex","title":"Better Auth Convex Local Integration","description":"better-auth-convex is a JavaScript/TypeScript library designed to integrate the better-auth authentication solution directly into a Convex application's schema, offering an alternative to the official component-based approach. The current stable version is 0.5.1, with development showing a consistent release cadence of patch and minor updates. Its primary differentiation lies in placing authentication tables within the application's own schema, allowing for direct database access without the latency associated with ctx.runQuery or ctx.runMutation overhead. This approach also ensures a unified context, enabling auth triggers to directly access and modify application tables transactionally, and provides full TypeScript inference across the entire schema. This library requires better-auth and @convex-dev/better-auth as peer dependencies and is primarily used in a Node.js/Convex environment.","status":"active","version":"0.5.1","language":"javascript","source_language":"en","source_url":"https://github.com/udecode/better-auth-convex","tags":["javascript","convex","auth","authentication","better-auth","typescript"],"install":[{"cmd":"npm install better-auth-convex","lang":"bash","label":"npm"},{"cmd":"yarn add better-auth-convex","lang":"bash","label":"yarn"},{"cmd":"pnpm add better-auth-convex","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core authentication logic dependency, specified as a peer dependency.","package":"@convex-dev/better-auth","optional":false},{"reason":"Core authentication library, installed alongside and used by the integration.","package":"better-auth","optional":false}],"imports":[{"note":"ESM-only usage is standard for modern Convex development, especially when shipping TypeScript types. Avoid CommonJS `require` syntax.","wrong":"const { createClient } = require('better-auth-convex')","symbol":"createClient","correct":"import { createClient } from 'better-auth-convex'"},{"note":"This function is used to create an internal API handler for authentication operations. It is designed for ESM environments.","wrong":"const { createApi } = require('better-auth-convex')","symbol":"createApi","correct":"import { createApi } from 'better-auth-convex'"},{"note":"AuthFunctions is a TypeScript type. Always use `import type` to prevent it from being bundled as a runtime import, which can lead to errors or larger bundle sizes.","wrong":"import { AuthFunctions } from 'better-auth-convex'","symbol":"AuthFunctions","correct":"import type { AuthFunctions } from 'better-auth-convex'"},{"note":"Prior to v0.4.6, `createSchema` was exported directly from the main package. Since v0.4.6, it was moved to a dedicated subpath to resolve Convex bundler errors related to Node.js `path` module imports.","wrong":"import { createSchema } from 'better-auth-convex'","symbol":"createSchema","correct":"import { createSchema } from 'better-auth-convex/schema'"}],"quickstart":{"code":"// convex/auth.config.ts\nimport { getAuthConfigProvider } from \"@convex-dev/better-auth/auth-config\";\nimport type { AuthConfig } from \"convex/server\";\n\nexport default {\n  providers: [getAuthConfigProvider({ jwks: process.env.JWKS ?? '' })],\n} satisfies AuthConfig;\n\n// convex/auth.ts\nimport { betterAuth } from \"better-auth\";\nimport { convex } from \"@convex-dev/better-auth/plugins\";\nimport { admin, organization } from \"better-auth/plugins\"; // Optional plugins\nimport {\n  type AuthFunctions,\n  createClient,\n  createApi\n} from \"better-auth-convex\";\nimport { internal } from \"./_generated/api\";\nimport type { MutationCtx, QueryCtx, GenericCtx } from \"./_generated/server\";\nimport type { DataModel } from \"./_generated/dataModel\";\nimport schema from \"./schema\"; // YOUR app schema with auth tables\nimport authConfig from \"./auth.config\";\n\n// 1. Internal API functions for auth operations\nconst authFunctions: AuthFunctions = internal.auth;\n\n// 2. Auth client with triggers that run in your app context\nexport const authClient = createClient<DataModel, typeof schema>({\n  authFunctions,\n  schema,\n  triggers: {\n    user: {\n      beforeCreate: async (_ctx, data) => {\n        const username =\n          data.username?.trim() ||\n          data.email?.split(\"@\")[0] ||\n          `user-${Date.now()}`;\n\n        return {\n          ...data,\n          username\n        };\n      },\n      onCreate: async (ctx, user) => {\n        const orgId = await ctx.db.insert(\"organization\", {\n          name: `${user.name}'s Workspace`,\n          slug: `personal-${user._id}`\n        });\n\n        await ctx.db.patch(user._id, {\n          personalOrganizationId: orgId\n        });\n      },\n      beforeDelete: async (ctx, user) => {\n        if (user.personalOrganizationId) {\n          await ctx.db.delete(user.personalOrganizationId);\n        }\n        return user;\n      }\n    },\n    session: {\n      onCreate: async (ctx, session) => {\n        // Handle session creation logic, e.g., logging or analytics\n      }\n    }\n  }\n});\n\nexport const auth = betterAuth<\n  typeof schema,\n  MutationCtx<DataModel>,\n  QueryCtx<DataModel>,\n  GenericCtx<DataModel>\n>({\n  authConfig,\n  authClient,\n  plugins: [\n    convex({\n      internal,\n      authClient,\n      schema\n    }),\n    admin({ authClient }),\n    organization({ authClient })\n  ]\n});","lang":"typescript","description":"This quickstart demonstrates the core setup for `better-auth-convex`, including defining the `auth.config.ts` and `auth.ts` files. It shows how to create an `authClient` with custom `user` and `session` triggers for lifecycle management, such as setting a default username, creating a personal organization for new users, and cleaning up data upon user deletion. It also illustrates how to combine these with `betterAuth` and Convex-specific plugins."},"warnings":[{"fix":"Before deploying, write and execute a migration script to transfer any existing authentication data from the component-scoped tables to your application's database tables.","message":"This package fundamentally alters where Better Auth tables are stored, moving them from a component schema into your main application schema. This requires a manual migration script if you are moving an existing `@convex-dev/better-auth` component-based deployment to `better-auth-convex`.","severity":"breaking","affected_versions":">=0.1.0"},{"fix":"Consult the official `@convex-dev/better-auth` migration guide for version 0.10 at `https://labs.convex.dev/better-auth/migrations/migrate-to-0-10` and adapt your code accordingly.","message":"Version 0.5.0 introduces compatibility with `@convex-dev/better-auth@0.10.4` and `better-auth@1.4.7`. Migrating to this version requires following the upstream migration guide for `@convex-dev/better-auth@0.10` to ensure API consistency.","severity":"breaking","affected_versions":">=0.5.0"},{"fix":"Update your Convex internal API definitions and any calling code to reflect `getLatestJwks` as an internal action rather than a mutation. For example, change `internal.auth.getLatestJwks` to `internal.auth.action.getLatestJwks` if you follow the recommended API structure.","message":"In version 0.5.1, the `getLatestJwks` function was changed from an internal mutation to an internal action. This affects how it is called and defined in your Convex internal API.","severity":"breaking","affected_versions":">=0.5.1"},{"fix":"Pass the `skipValidation: true` option to `createApi` when creating your internal API functions (e.g., `createApi({ ..., skipValidation: true })`) to use generic `v.any()` validators and reduce bundle size.","message":"By default, internal API functions generated by `createApi` include typed validators, which can significantly increase your bundle size, especially with complex schemas. For internal functions where type validation is less critical or handled by other mechanisms, this can lead to larger deployment bundles and slower build times.","severity":"gotcha","affected_versions":">=0.4.9"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Upgrade `better-auth-convex` to version `0.4.6` or later to ensure the `dist` folder and compiled assets are properly included in the npm package.","cause":"The `dist` folder, which contains the compiled JavaScript output, was missing from the published npm package in some earlier versions, preventing bundlers from resolving the package correctly.","error":"Module not found: Error: Can't resolve 'better-auth-convex' in '...'"},{"fix":"For `createSchema`, explicitly import it from the dedicated subpath: `import { createSchema } from 'better-auth-convex/schema'`. Ensure you are using `better-auth-convex@0.4.6` or a newer version where this fix was implemented.","cause":"Prior to `v0.4.6`, the `createSchema` utility was directly exported from the main package entry point, which caused issues with the Convex bundler trying to resolve Node.js-specific built-in modules like `path` that are not available in the Convex environment.","error":"Convex bundler error: 'path' module not found"}],"ecosystem":"npm"}