Create a Database Adapter
Learn how to create a custom database adapter for Better-Auth using createAdapter
.
Our createAdapter
function is designed to be very flexible, and we've done our best to make it easy to understand and use.
Our hope is to allow you to focus on writing database logic, and not have to worry about how the adapter is working with Better-Auth.
Anything from custom schema configurations, custom ID generation, safe JSON parsing, and more is handled by the createAdapter
function.
All you need to do is provide the database logic, and the createAdapter
function will handle the rest.
Quick Start
Get things ready
- Import
createAdapter
. - Create
CustomAdapterConfig
interface that represents your adapter config options. - Create the adapter!
Configure the adapter
The config
object is mostly used to provide information about the adapter to Better-Auth.
We try to minimize the amount of code you need to write in your adapter functions, and these config
options are used to help us do that.
Learn more about the config
object here.
Create the adapter
The adapter
function is where you write the code that interacts with your database.
Learn more about the adapter
function here.
Adapter
The adapter
function is where you write the code that interacts with your database.
If you haven't already, check out the options
object in the config section, as it can be useful for your adapter.
Before we get into the adapter function, let's go over the parameters that are available to you.
options
: The Better Auth options.schema
: The schema from the user's Better Auth instance.debugLog
: The debug log function.getField
: The get field function.getDefaultModelName
: The get default model name function.getDefaultFieldName
: The get default field name function.getFieldAttributes
: The get field attributes function.
Adapter Methods
- All
model
values are already transformed into the correct model name for the database based on the end-user's schema configuration.- This also means that if you need access to the
schema
version of a given model, you can't use this exactmodel
value, you'll need to use thegetDefaultModelName
function provided in the options to convert themodel
to theschema
version.
- This also means that if you need access to the
- We will automatically fill in any missing fields you return based on the user's
schema
configuration. - Any method that includes a
select
parameter, is only for the purpose of getting data from your database more efficiently. You do not need to worry about only returning what theselect
parameter states, as we will handle that for you.
create
method
The create
method is used to create a new record in the database.
Note:
In all cases, the id
field is automatically generated inside of the data
object unless the user has enabled the useNumberId
option, or if generateId
is false
in the user's Better-Auth config.
In these cases, it's expected that the users database will handle the id generation.
parameters:
model
: The model/table name that new data will be inserted into.data
: The data to insert into the database.
Make sure to return the data that is inserted into the database.
update
method
The update
method is used to update a record in the database.
parameters:
model
: The model/table name that the record will be updated in.where
: Thewhere
clause to update the record by.update
: The data to update the record with.
Make sure to return the data in the row which is updated. This includes any fields that were not updated.
updateMany
method
The updateMany
method is used to update multiple records in the database.
parameters:
model
: The model/table name that the records will be updated in.where
: Thewhere
clause to update the records by.update
: The data to update the records with.
delete
method
The delete
method is used to delete a record from the database.
parameters:
model
: The model/table name that the record will be deleted from.where
: Thewhere
clause to delete the record by.
deleteMany
method
The deleteMany
method is used to delete multiple records from the database.
parameters:
model
: The model/table name that the records will be deleted from.where
: Thewhere
clause to delete the records by.
findOne
method
The findOne
method is used to find a single record in the database.
parameters:
model
: The model/table name that the record will be found in.where
: Thewhere
clause to find the record by.select
: Theselect
clause to return.
findMany
method
The findMany
method is used to find multiple records in the database.
parameters:
model
: The model/table name that the records will be found in.where
: Thewhere
clause to find the records by.limit
: The limit of records to return.sortBy
: ThesortBy
clause to sort the records by.offset
: The offset of records to return.
Make sure to return the array of data that is found in the database.
count
method
The count
method is used to count the number of records in the database.
parameters:
model
: The model/table name that the records will be counted in.where
: Thewhere
clause to count the records by.
options
(optional)
The options
object is for any potential config that you got from your custom adapter options.
createSchema
(optional)
The createSchema
method allows the Better Auth CLI to generate a schema for the database.
parameters:
tables
: The tables from the user's Better-Auth instance schema; which is expected to be generated into the schema file.file
: The file the user may have passed in to thegenerate
command as the expected schema file output path.
Test your adapter
We've provided a test suite that you can use to test your adapter. It requires you to use vitest
.
Numeric ID tests
If your database supports numeric ids, then you should run this test as well:
Config
The config
object is used to provide information about the adapter to Better-Auth.
We highly recommend going through and reading each provided option below, as it will help you understand how to properly configure your adapter.
Required Config
adapterId
A unique identifier for the adapter.
adapterName
The name of the adapter.
Optional Config
supportsNumericIds
Whether the database supports numeric ids. If this is set to false
and the users config has enabled useNumberId
, then we will throw an error.
supportsJSON
Whether the database supports JSON. If the database doesn't support JSON, we will use a string
to save the JSON data.And when we retrieve the data, we will safely parse the string
back into a JSON object.
supportsDates
Whether the database supports dates. If the database doesn't support dates, we will use a string
to save the date. (ISO string) When we retrieve the data, we will safely parse the string
back into a Date
object.
supportsBooleans
Whether the database supports booleans. If the database doesn't support booleans, we will use a 0
or 1
to save the boolean value. When we retrieve the data, we will safely parse the 0
or 1
back into a boolean value.
usePlural
Whether the table names in the schema are plural. This is often defined by the user, and passed down through your custom adapter options. If you do not intend to allow the user to customize the table names, you can ignore this option, or set this to false
.
debugLogs
Used to enable debug logs for the adapter. You can pass in a boolean, or an object with the following keys: create
, update
, updateMany
, findOne
, findMany
, delete
, deleteMany
, count
.
If any of the keys are true
, the debug logs will be enabled for that method.
disableIdGeneration
Whether to disable id generation. If this is set to true
, then the user's generateId
option will be ignored.
customIdGenerator
If your database only supports a specific custom id generation, then you can use this option to generate your own IDs.
mapKeysTransformInput
If your database uses a different key name for a given situation, you can use this option to map the keys. This is useful for databases that expect a different key name for a given situation.
For example, MongoDB uses _id
while in Better-Auth we use id
.
Each key in the returned object represents the old key to replace. The value represents the new key.
This can be a partial object that only transforms some keys.
mapKeysTransformOutput
If your database uses a different key name for a given situation, you can use this option to map the keys. This is useful for databases that use a different key name for a given situation.
For example, MongoDB uses _id
while in Better-Auth we use id
.
Each key in the returned object represents the old key to replace. The value represents the new key.
This can be a partial object that only transforms some keys.
customTransformInput
If you need to transform the input data before it is saved to the database, you can use this option to transform the data.
If you're using supportsJSON
, supportsDates
, or supportsBooleans
, then
the transformations will be applied before your customTransformInput
function is called.
The customTransformInput
function receives the following arguments:
data
: The data to transform.field
: The field that is being transformed.fieldAttributes
: The field attributes of the field that is being transformed.select
: Theselect
values which the query expects to return.model
: The model that is being transformed.schema
: The schema that is being transformed.options
: Better Auth options.
The customTransformInput
function runs at every key in the data object of a given action.
customTransformOutput
If you need to transform the output data before it is returned to the user, you can use this option to transform the data. The customTransformOutput
function is used to transform the output data.
Similar to the customTransformInput
function, it runs at every key in the data object of a given action, but it runs after the data is retrieved from the database.