Authentication
VexCMS supports authentication via auth adapters. An auth adapter introspects your auth provider’s schema and converts it into standard Vex collections that are merged with your user-defined collections.
How it works
Section titled “How it works”Auth adapters implement the VexAuthAdapter interface. They expose:
name— provider identifier (e.g."better-auth")collections— auth collections (user, session, account, verification, etc.)userCollection— the slug of the collection that stores user documents
These collections are passed to defineConfig({ auth: … }) and merged
automatically with your user-defined collections via
mergeAuthCollections.
Merge behavior
Section titled “Merge behavior”Auth collections merge with user-defined collections following these rules:
- Protected collections — auth collections marked as
protectedcannot be overridden by user-defined collections with the same slug. Attempting to do so throws aVexAuthConfigError. - Locked fields — fields on auth collections with
meta.locked: trueare preserved during merge. User-defined fields with the same key are ignored. - Unlocked fields — user-defined fields override or extend auth fields.
- User-only collections — user-defined collections with no matching auth collection are added as-is.
- Auth-only collections — auth collections with no matching user collection are appended at the end.
Better Auth
Section titled “Better Auth”The @vexcms/better-auth package provides a betterAuthAdapter() that
introspects a Better Auth configuration and
converts its tables into Vex collections.
import { betterAuthAdapter } from "@vexcms/better-auth";
export const authOptions = { // your Better Auth configuration};
// vex.config.tsimport { defineConfig } from "@vexcms/core";import { betterAuthAdapter } from "@vexcms/better-auth";import { authOptions } from "./auth/options";
export default defineConfig({ auth: betterAuthAdapter({ config: authOptions }), collections: [posts, authors],});Field mapping
Section titled “Field mapping”betterAuthAdapter() maps Better Auth DBFieldAttribute types to Vex field
builders:
| Better Auth type | Vex field |
|------------------|-----------|
| string | text() |
| boolean | checkbox() |
| number | number() |
| date, timestamp | date() |
| json | text() (fallback) |
| string[] (enum) | select() |
| references | relationship() |
System fields are automatically marked as admin.readOnly and meta.locked.
Sensitive fields (hashedPassword, twoFactorSecret, etc.) are hidden from
the admin UI with admin.hidden: true.
Extending the user collection
Section titled “Extending the user collection”The user collection is not protected, so you can extend it with user-defined fields:
const user = defineCollection({ slug: "user", fields: { bio: text(), publicProfile: checkbox({ defaultValue: true }), },});
export default defineConfig({ auth: betterAuthAdapter({ config: authOptions }), collections: [user, posts],});Locked fields (email, emailVerified, createdAt, etc.) are preserved. Your
unlocked fields (bio, publicProfile) are merged in.
Admin UI behavior
Section titled “Admin UI behavior”Auth collections appear in the admin sidebar alongside user-defined collections. System fields are read-only and cannot be edited. User-editable fields (name, email, image, role, etc.) can be modified through the standard document edit form.