MongoDB
MongoDB support ships in the external better_auth-mongo-adapter gem, so
SQL-only applications do not install the MongoDB driver.
MongoDB support maps Better Auth's logical id field to Mongo _id. Core
collections use upstream-compatible singular names by default: user,
session, account, and verification.
Install Dependencies
gem "better_auth"
gem "better_auth-mongo-adapter"bundle installExample Usage
require "better_auth"
require "better_auth/mongo_adapter"
mongo_client = Mongo::Client.new(
ENV.fetch("MONGODB_URL", "mongodb://127.0.0.1:27017/better_auth")
)
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
base_url: ENV.fetch("BETTER_AUTH_URL"),
database: ->(options) {
BetterAuth::Adapters::MongoDB.new(
options,
database: mongo_client.database,
client: mongo_client,
transaction: false
)
}
)The lambda form lets Better Auth pass the final configuration into the adapter, including plugins, custom schemas, and advanced database options.
The example disables transactions because standalone local MongoDB does not
support multi-document transactions. Use the default transaction behavior, or
pass transaction: true, only when your MongoDB deployment is replica-set
capable.
Schema generation & migration
MongoDB does not require SQL schema generation or migration. The adapter writes
documents using Better Auth storage field names, including custom model names,
custom field names, plugin schemas, and additional_fields.
Production deployments should still create indexes for unique and lookup
fields. The adapter exposes ensure_indexes! as an explicit setup helper:
adapter = BetterAuth::Adapters::MongoDB.new(
options,
database: mongo_client.database,
client: mongo_client,
transaction: false
)
adapter.ensure_indexes!ensure_indexes! reads Better Auth schema metadata and requests indexes for
fields marked unique: true or index: true, including plugin schemas and
custom model or field names. It skips Mongo _id because MongoDB creates that
index automatically.
MongoDB Schema Generation | MongoDB Schema Migration |
|---|---|
| Not required | Not required |
Joins (Experimental)
Enable experimental joins when you want Better Auth to ask the MongoDB adapter to fetch related records in one adapter call.
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
experimental: { joins: true },
database: ->(options) {
BetterAuth::Adapters::MongoDB.new(
options,
database: mongo_client.database,
client: mongo_client,
transaction: false
)
}
)The MongoDB adapter supports native joins for core relationships and plugin
models. Joins can use upstream-style on configuration or be inferred from
schema references, so plugin models with reference fields work the same way
as core session -> user and user -> account joins.
Schema
The MongoDB adapter stores Better Auth logical fields as storage field names.
| Better Auth field | MongoDB field |
|---|---|
id | _id |
emailVerified | email_verified |
userId | user_id |
createdAt | created_at |
expiresAt | expires_at |
JSON fields are stored as JSON strings and parsed on output, matching upstream adapter behavior. Array fields are stored natively unless a field is an id reference, in which case values are normalized to the configured id type.
By default, generated ids are stored as MongoDB ObjectId values. If you set
advanced: { database: { generate_id: "uuid" } }, generated ids and id
references are stored as native BSON UUID values and returned to Ruby callers as
UUID strings. If you provide a callable custom id generator, the returned value
is stored as-is.
Ruby's adapters accept scalar values for in and not_in filters and coerce
them to a one-element list. This is an intentional Ruby adapter-family
adaptation; upstream's TypeScript adapter factory validates those filters
before the Mongo adapter internals receive them.
Additional Information
- Transactions are enabled when a client is provided unless
transaction: falseis passed. If your MongoDB deployment does not support transactions, passtransaction: false. - MongoDB transactions require a replica set, even for a single local node.
- Use
use_plural: truewhen you want collection names from Better Auth schemamodel_namevalues instead of the default singular collection names. - The upstream TypeScript adapter exposes
debugLogs; Better Auth Ruby does not currently have an adapter-level debug logging contract, so that option is not ported.
BetterAuth::Adapters::MongoDB.new(
options,
database: mongo_client.database,
client: mongo_client,
transaction: false,
use_plural: true
)Testing Transactions Locally
The Mongo adapter test suite runs transaction rollback coverage when
BETTER_AUTH_MONGODB_REPLICA_SET_URL points to a replica-set-capable MongoDB
URL.
BETTER_AUTH_MONGODB_REPLICA_SET_URL="mongodb://127.0.0.1:27017/better-auth-ruby-transaction-test?replicaSet=rs0" \
bundle exec rake test