SQLite
SQLite is supported by the core better_auth gem through the sqlite3 gem. It
is useful for local development, single-node Rack apps, tests, and small
deployments.
Use the lambda form when configuring the direct adapter. Better Auth passes the
final configuration into the lambda, so the adapter sees plugins, custom model
names, custom field names, and advanced.database.generate_id.
Install Dependencies
gem "better_auth"
gem "sqlite3"bundle installExample Usage
require "better_auth"
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
base_url: ENV.fetch("BETTER_AUTH_URL"),
database: ->(options) {
BetterAuth::Adapters::SQLite.new(
options,
path: "storage/better_auth.sqlite3"
)
}
)You may also pass an existing SQLite3::Database object when your application
owns connection lifecycle.
require "sqlite3"
database = SQLite3::Database.new("storage/better_auth.sqlite3")
database.results_as_hash = true
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
database: ->(options) {
BetterAuth::Adapters::SQLite.new(
options,
connection: database
)
}
)Rails
Rails apps can use better_auth-rails with ActiveRecord and SQLite.
gem "better_auth-rails"
gem "sqlite3"bin/rails generate better_auth:install
bin/rails db:migrateSchema generation & migration
The Ruby schema helpers generate SQLite DDL from the same Better Auth
configuration used at runtime, including plugins, custom model names, custom
field names, and additional_fields.
SQLite Schema Generation | SQLite Schema Migration |
|---|---|
| ✅ Supported | ✅ Supported |
config = BetterAuth::Configuration.new(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
database: :memory,
plugins: []
)
statements = BetterAuth::Schema::SQL.create_statements(
config,
dialect: :sqlite
)
puts statements.join("\n\n")require "better_auth"
require "sqlite3"
config = BetterAuth::Configuration.new(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
database: :memory,
plugins: []
)
statements = BetterAuth::Schema::SQL.create_statements(
config,
dialect: :sqlite
)
database = SQLite3::Database.new("storage/better_auth.sqlite3")
statements.each { |sql| database.execute(sql) }Joins (Experimental)
Enable experimental joins when you want Better Auth to ask the database 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::SQLite.new(
options,
path: "storage/better_auth.sqlite3"
)
}
)The SQLite adapter supports native joins for core relationships and for plugin
schema relationships declared with references. Rails uses generated
ActiveRecord associations for the same schema-driven relationships.
Schema
The adapter stores Better Auth logical fields as snake_case SQLite columns.
| Better Auth field | SQLite column |
|---|---|
emailVerified | email_verified |
userId | user_id |
createdAt | created_at |
expiresAt | expires_at |
JSON-like fields are stored as JSON text and parsed on output, booleans are
stored as integers, and ids are generated as hex strings by default. Set
advanced: { database: { generate_id: "uuid" } } to generate UUID strings
instead.
Additional Information
- The direct adapter enables foreign keys with
PRAGMA foreign_keys = ON. - The direct adapter supports the shared Better Auth CRUD contract, where operators, sorting, pagination, counts, transactions, and native joins.
- Rails apps should prefer Rails migrations generated by
better_auth-rails; direct SQL generation is intended for non-Rails apps or custom migration workflows.