Skip to content
Migrating from NextAuth.js v4? Read our migration guide.
API reference
@auth/drizzle-adapter

@auth/drizzle-adapter

Official Drizzle ORM adapter for Auth.js / NextAuth.js.

Installation

npm install drizzle-orm @auth/drizzle-adapter
npm install drizzle-kit --save-dev

mysqlAccountsTable

Re-exports mysqlAccountsTable

mysqlSessionsTable

Re-exports mysqlSessionsTable

mysqlUsersTable

Re-exports mysqlUsersTable

mysqlVerificationTokensTable

Re-exports mysqlVerificationTokensTable

postgresAccountsTable

Re-exports postgresAccountsTable

postgresSessionsTable

Re-exports postgresSessionsTable

postgresUsersTable

Re-exports postgresUsersTable

postgresVerificationTokensTable

Re-exports postgresVerificationTokensTable

sqliteAccountsTable

Re-exports sqliteAccountsTable

sqliteSessionsTable

Re-exports sqliteSessionsTable

sqliteUsersTable

Re-exports sqliteUsersTable

sqliteVerificationTokensTable

Re-exports sqliteVerificationTokensTable

DrizzleAdapter()

DrizzleAdapter<SqlFlavor>(db, schema?): Adapter

Add this adapter to your auth.ts Auth.js configuration object:

auth.ts
import NextAuth from "next-auth"
import Google from "next-auth/providers/google"
import { DrizzleAdapter } from "@auth/drizzle-adapter"
import { db } from "./schema"
 
export const { handlers, auth } = NextAuth({
  adapter: DrizzleAdapter(db),
  providers: [
    Google,
  ],
})

If you want to use your own tables, you can pass them as a second argument

auth.ts
import NextAuth from "next-auth"
import Google from "next-auth/providers/google"
import { DrizzleAdapter } from "@auth/drizzle-adapter"
import { db, accounts, sessions, users, verificationTokens } from "./schema"
 
export const { handlers, auth } = NextAuth({
  adapter: DrizzleAdapter(db, { usersTable: users, accountsTable: accounts, sessionsTable: sessions, verificationTokensTable: verificationTokens }),
  providers: [
    Google,
  ],
})

Setup

First, create a schema that includes the minimum requirements for a next-auth adapter. You can select your favorite SQL flavor below and copy it. Additionally, you may extend the schema from the minimum requirements to suit your needs.

Postgres

schema.ts
import {
  timestamp,
  pgTable,
  text,
  primaryKey,
 integer
} from "drizzle-orm/pg-core"
import type { AdapterAccount } from '@auth/core/adapters'
import { randomUUID } from "crypto"
 
export const users = pgTable("user", {
 id: text("id").primaryKey().$defaultFn(() => randomUUID()),
 name: text("name"),
 email: text("email").notNull().unique(),
 emailVerified: timestamp("emailVerified", { mode: "date" }),
 image: text("image"),
})
 
export const accounts = pgTable(
"account",
{
  userId: text("userId")
    .notNull()
    .references(() => users.id, { onDelete: "cascade" }),
  type: text("type").notNull(),
  provider: text("provider").notNull(),
  providerAccountId: text("providerAccountId").notNull(),
  refresh_token: text("refresh_token"),
  access_token: text("access_token"),
  expires_at: integer("expires_at"),
  token_type: text("token_type"),
  scope: text("scope"),
   id_token: text("id_token"),
  session_state: text("session_state"),
},
(account) => ({
  userIdIdx: index().on(account.userId),
  compoundKey: primaryKey({ columns: [account.provider, account.providerAccountId] }),
})
)
 
export const sessions = pgTable("session", {
 id: text("id").primaryKey().$defaultFn(() => randomUUID()),
 sessionToken: text("sessionToken").notNull().unique(),
 userId: text("userId")
   .notNull()
   .references(() => users.id, { onDelete: "cascade" }),
 expires: timestamp("expires", { mode: "date" }).notNull(),
}, (session) => ({
  userIdIdx: index().on(session.userId)
}))
 
export const verificationTokens = pgTable(
 "verificationToken",
 {
   identifier: text("identifier").notNull(),
   token: text("token").notNull().unique(),
   expires: timestamp("expires", { mode: "date" }).notNull(),
 },
 (vt) => ({
   compoundKey: primaryKey({ columns: [vt.identifier, vt.token] }),
 })
)

MySQL

schema.ts
import {
 int,
 timestamp,
 mysqlTable,
 primaryKey,
 varchar,
} from "drizzle-orm/mysql-core"
import type { AdapterAccount } from "@auth/core/adapters"
 
export const users = mysqlTable("user", {
 id: varchar("id", { length: 255 }).primaryKey().$defaultFn(() => randomUUID()),
 name: varchar("name", { length: 255 }),
 email: varchar("email", { length: 255 }).notNull().unique(),
 emailVerified: timestamp("emailVerified", { mode: "date", fsp: 3 }),
 image: varchar("image", { length: 255 }),
})
 
export const accounts = mysqlTable(
 "account",
  {
   userId: varchar("userId", { length: 255 })
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
   type: varchar("type", { length: 255 }).notNull(),
   provider: varchar("provider", { length: 255 }).notNull(),
   providerAccountId: varchar("providerAccountId", { length: 255 }).notNull(),
   refresh_token: varchar("refresh_token", { length: 255 }),
   access_token: varchar("access_token", { length: 255 }),
   expires_at: int("expires_at"),
  token_type: varchar("token_type", { length: 255 }),
  scope: varchar("scope", { length: 255 }),
  id_token: varchar("id_token", { length: 2048 }),
  session_state: varchar("session_state", { length: 255 }),
},
(account) => ({
   compoundKey: primaryKey({
       columns: [account.provider, account.providerAccountId],
     }),
     userIdIdx: index('Account_userId_index').on(account.userId)
})
)
 
export const sessions = mysqlTable("session", {
 id: varchar("id", { length: 255 }).primaryKey().$defaultFn(() => randomUUID()),
 sessionToken: varchar("sessionToken", { length: 255 }).notNull().unique(),
 userId: varchar("userId", { length: 255 })
   .notNull()
   .references(() => users.id, { onDelete: "cascade" }),
 expires: timestamp("expires", { mode: "date" }).notNull(),
}, (session) => ({
 userIdIdx: index('Session_userId_index').on(session.userId)
}))
 
export const verificationTokens = mysqlTable(
"verificationToken",
{
  identifier: varchar("identifier", { length: 255 }).notNull(),
  token: varchar("token", { length: 255 }).notNull().unique(),
  expires: timestamp("expires", { mode: "date" }).notNull(),
},
(vt) => ({
  compoundKey: primaryKey({ columns: [vt.identifier, vt.token] }),
})
)

SQLite

schema.ts
import { integer, sqliteTable, text, primaryKey } from "drizzle-orm/sqlite-core"
import type { AdapterAccount } from "@auth/core/adapters"
 
export const users = sqliteTable("user", {
 id: text("id").primaryKey().$defaultFn(() => randomUUID()),
 name: text("name"),
 email: text("email").notNull().unique(),
 emailVerified: integer("emailVerified", { mode: "timestamp_ms" }),
 image: text("image"),
})
 
export const accounts = sqliteTable(
 "account",
 {
   userId: text("userId")
     .notNull()
     .references(() => users.id, { onDelete: "cascade" }),
   type: text("type").notNull(),
   provider: text("provider").notNull(),
   providerAccountId: text("providerAccountId").notNull(),
   refresh_token: text("refresh_token"),
   access_token: text("access_token"),
   expires_at: integer("expires_at"),
   token_type: text("token_type"),
   scope: text("scope"),
   id_token: text("id_token"),
   session_state: text("session_state"),
 },
 (account) => ({
   compoundKey: primaryKey({
       columns: [account.provider, account.providerAccountId],
     }),
     userIdIdx: index('Account_userId_index').on(account.userId)
 })
)
 
export const sessions = sqliteTable("session", {
id: text("id").primaryKey().$defaultFn(() => randomUUID())
sessionToken: text("sessionToken").notNull().unique(),
userId: text("userId")
  .notNull()
  .references(() => users.id, { onDelete: "cascade" }),
expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
}, (table) => ({
 userIdIdx: index('Session_userId_index').on(table.userId)
}))
 
export const verificationTokens = sqliteTable(
"verificationToken",
{
  identifier: text("identifier").notNull(),
  token: text("token").notNull().unique(),
  expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
},
(vt) => ({
  compoundKey: primaryKey({ columns: [vt.identifier, vt.token] }),
})
)

Migrating your database

With your schema now described in your code, you’ll need to migrate your database to your schema.

For full documentation on how to run migrations with Drizzle, visit the Drizzle documentation.


Type parameters

Type parameter
SqlFlavor extends SqlFlavorOptions

Parameters

ParameterType
dbSqlFlavor
schema?DefaultSchema<SqlFlavor>

Returns

Adapter

Auth.js © Balázs Orbán and Team - 2024