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

Gemfile
gem "better_auth"
gem "better_auth-mongo-adapter"
Terminal
bundle install

Example Usage

config/auth.rb
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:

setup/mongo_indexes.rb
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 requiredNot required

Joins (Experimental)

Enable experimental joins when you want Better Auth to ask the MongoDB adapter to fetch related records in one adapter call.

config/auth.rb
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 fieldMongoDB field
id_id
emailVerifiedemail_verified
userIduser_id
createdAtcreated_at
expiresAtexpires_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: false is passed. If your MongoDB deployment does not support transactions, pass transaction: false.
  • MongoDB transactions require a replica set, even for a single local node.
  • Use use_plural: true when you want collection names from Better Auth schema model_name values 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.
config/auth.rb
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.

Terminal
BETTER_AUTH_MONGODB_REPLICA_SET_URL="mongodb://127.0.0.1:27017/better-auth-ruby-transaction-test?replicaSet=rs0" \
  bundle exec rake test

On this page