Skip to content
Migrating from NextAuth.js v4? Read our migration guide.
Getting Started
Adapters
Prisma

Prisma Adapter

Resources

Setup

Installation

npm install @prisma/client @auth/prisma-adapter
npm install prisma --save-dev

Environment Variables

DATABASE_URL=postgres://postgres:adminadmin@0.0.0.0:5432/db

Configuration

⚠️

We recommend using version @prisma/client@5.12.0 or above if using middleware or any other edge runtime(s). See edge compatibility below for more information.

./auth.ts
import NextAuth from "next-auth"
import { PrismaAdapter } from "@auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"
 
const prisma = new PrismaClient()
 
export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: PrismaAdapter(prisma),
  providers: [],
})

Edge Compatibility

Prisma has shipped edge runtime support for their client in version 5.12.0. You can read more about it on their edge documentation. This requires specific database drivers and therefore is only compatible with certain database types / hosting providers. Check their list of supported drivers before getting started. You can check out an example Auth.js application with next-auth and Prisma on the edge here.

For more about edge compatibility in general, check out our edge compatibility guide.

The original database edge-runtime workaround, to split your auth.ts configuration into two, will be kept below.

Old Edge Workaround

At the moment, Prisma is still working on being fully compatible with edge runtimes like Vercel’s. See the issue being tracked here, and Prisma’s announcement about early edge support in the 5.9.1 changelog. There are two options to deal with this issue:

  • Use the Prisma’s Accelerate feature
  • Switch to the jwt session strategy

Using Prisma with the jwt session strategy and @prisma/client@5.9.1 or above doesn’t require any additional modifications, other than ensuring you don’t do any database queries in your middleware.

Since @prisma/client@5.9.1, Prisma no longer throws about being incompatible with the edge runtime at instantiation, but at query time. Therefore, it is possible to import it in files being used in your middleware as long as you do not execute any queries in your middleware.

Schema

You need to use at least Prisma 2.26.0. Create a schema file at prisma/schema.prisma with the following models.

Apply Schema

This will create an SQL migration file and execute it:

npm exec prisma migrate dev

Note that you will need to specify your database connection string in the environment variable DATABASE_URL. You can do this by setting it in a .env file at the root of your project. Note Prisma doesn’t support .env.local syntax, it must be named .env. For more information, check out their environment variables docs.

Generate Prisma Client

prisma migrate dev will also generate the Prisma client, but if you need to generate it again manually you can run the following command.

npm exec prisma generate

Development Workflow

When you’re working on your application and making changes to your database schema, you’ll need to run the migrate command again every time you make changes to the schema in order for Prisma to (1) generate a migration file and apply it to the underlying database and (2) regenerate the Prisma client in your project with the latest types and model methods.

npm exec prisma migrate dev

Naming Conventions

If mixed snake_case and camelCase column names is an issue for you and/or your underlying database system, we recommend using Prisma’s @map() feature to change the field names. This won’t affect Auth.js, but will allow you to customize the column names to whichever naming convention you prefer.

For example, moving to snake_case and plural table names.

schema.prisma
model Account {
  id                 String  @id @default(cuid())
  userId             String  @map("user_id")
  type               String
  provider           String
  providerAccountId  String  @map("provider_account_id")
  refresh_token      String? @db.Text
  access_token       String? @db.Text
  expires_at         Int?
  token_type         String?
  scope              String?
  id_token           String? @db.Text
  session_state      String?
 
  user User @relation(fields: [userId], references: [id], onDelete: Cascade)
 
  @@unique([provider, providerAccountId])
  @@map("accounts")
}
 
model Session {
  id           String   @id @default(cuid())
  sessionToken String   @unique @map("session_token")
  userId       String   @map("user_id")
  expires      DateTime
  user         User     @relation(fields: [userId], references: [id], onDelete: Cascade)
 
  @@map("sessions")
}
 
model User {
  id            String    @id @default(cuid())
  name          String?
  email         String?   @unique
  emailVerified DateTime? @map("email_verified")
  image         String?
  accounts      Account[]
  sessions      Session[]
 
  @@map("users")
}
 
model VerificationToken {
  identifier String
  token      String
  expires    DateTime
 
  @@unique([identifier, token])
  @@map("verificationtokens")
}
Auth.js © Balázs Orbán and Team - 2024