Skip to main content

Quickstart Guide

Get a working authentication system with phone OTP, email/password, and OAuth in under 5 minutes. This guide uses Next.js with the App Router and Prisma.
1

Install Packages

Install the core package, a database adapter, and the Next.js integration:
npm install @arraf-auth/core @arraf-auth/adapter-prisma @arraf-auth/nextjs
This guide uses Prisma. If you prefer Drizzle, install @arraf-auth/adapter-drizzle instead.
2

Set Up Prisma (if not already configured)

If you haven’t set up Prisma yet, initialize it:
npx prisma init
Add the Arraf Auth schema to your schema.prisma:
model User {
  id            String    @id @default(cuid())
  email         String?   @unique
  phone         String?   @unique
  name          String?
  emailVerified Boolean   @default(false)
  phoneVerified Boolean   @default(false)
  image         String?
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt
  
  sessions      Session[]
  accounts      Account[]
}

model Session {
  id        String   @id @default(cuid())
  userId    String
  token     String   @unique
  expiresAt DateTime
  ipAddress String?
  userAgent String?
  createdAt DateTime @default(now())
  
  user      User     @relation(fields: [userId], references: [id], onDelete: Cascade)
}

model Account {
  id                   String    @id @default(cuid())
  userId               String
  providerId           String
  accountId            String
  accessToken          String?
  refreshToken         String?
  accessTokenExpiresAt DateTime?
  createdAt            DateTime  @default(now())
  
  user                 User      @relation(fields: [userId], references: [id], onDelete: Cascade)
  
  @@unique([providerId, accountId])
}

model Verification {
  id         String   @id @default(cuid())
  identifier String
  token      String
  type       String
  expiresAt  DateTime
  attempts   Int      @default(0)
  createdAt  DateTime @default(now())
  
  @@unique([identifier, type])
}
Then push the schema to your database:
npx prisma db push
3

Create Prisma Client

Create a Prisma client instance at lib/prisma.ts:
lib/prisma.ts
import { PrismaClient } from "@prisma/client"

const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }

export const prisma =
  globalForPrisma.prisma ?? new PrismaClient()

if (process.env.NODE_ENV !== "production") {
  globalForPrisma.prisma = prisma
}
4

Configure Arraf Auth

Create your auth configuration at lib/auth.ts:
lib/auth.ts
import { createAuth } from "@arraf-auth/core"
import { prismaAdapter } from "@arraf-auth/adapter-prisma"
import { prisma } from "./prisma"

export const auth = createAuth({
  secret: process.env.AUTH_SECRET!,
  database: prismaAdapter(prisma),
  
  // Session configuration
  session: {
    strategy: "database", // or "jwt"
    cookieName: "arraf_session",
  },
  
  // OTP configuration for phone authentication
  otp: {
    length: 6,
    expiresIn: 300, // 5 minutes
    maxAttempts: 5,
  },
  
  // SMS provider for phone OTP
  sms: {
    send: async ({ to, message }) => {
      // TODO: Integrate with your SMS provider
      // Examples: Unifonic, Taqnyat, Msegat
      console.log(`SMS to ${to}: ${message}`)
      return { success: true }
    },
  },
})
Make sure to set AUTH_SECRET in your .env file. Generate a secure random string:
openssl rand -base64 32
5

Create API Route

Create a catch-all API route at app/api/auth/[...all]/route.ts:
app/api/auth/[...all]/route.ts
import { toNextHandlers } from "@arraf-auth/nextjs"
import { auth } from "@/lib/auth"

export const { GET, POST } = toNextHandlers(auth)
This exposes all authentication endpoints under /api/auth/*.
6

Use Phone OTP Authentication

Now you can authenticate users with their phone number. Here’s a complete example:
// 1. Send OTP to user's phone
const sendResponse = await fetch('/api/auth/otp/send', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    method: 'phone',
    phone: '0501234567' // Saudi phone number
  })
})

// 2. User receives SMS with 6-digit code
// 3. Verify the OTP code
const verifyResponse = await fetch('/api/auth/otp/verify', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    method: 'phone',
    phone: '0501234567',
    otp: '123456' // Code from SMS
  })
})

if (verifyResponse.ok) {
  // User is now authenticated!
  // Session cookie is automatically set
}
7

Get Current Session

Retrieve the authenticated user’s session:
import { getSession } from "@arraf-auth/nextjs"
import { auth } from "@/lib/auth"

export default async function Page() {
  const session = await getSession(auth)
  
  if (!session) {
    return <div>Not authenticated</div>
  }
  
  return (
    <div>
      <h1>Welcome, {session.user.name}!</h1>
      <p>Phone: {session.user.phone}</p>
    </div>
  )
}

Available Authentication Flows

Your authentication system now supports multiple flows:

Phone + OTP (Primary for Saudi Market)

// Send OTP
POST /api/auth/otp/send
{
  "method": "phone",
  "phone": "0501234567"
}

// Verify OTP
POST /api/auth/otp/verify
{
  "method": "phone",
  "phone": "0501234567",
  "otp": "123456"
}

Email + Password

// Sign up
POST /api/auth/sign-up
{
  "email": "[email protected]",
  "password": "secure-password",
  "name": "Ahmed"
}

// Sign in
POST /api/auth/sign-in
{
  "method": "email",
  "email": "[email protected]",
  "password": "secure-password"
}

OAuth

// Redirect to OAuth provider
GET /api/auth/sign-in/google
GET /api/auth/sign-in/github
OAuth providers require additional configuration. See the OAuth guide for details.

Next Steps

Phone + OTP Guide

Deep dive into phone authentication with SMS providers

Database Setup

Configure Prisma or Drizzle for your database

Session Management

Learn about JWT vs database sessions

OAuth Providers

Add Google and GitHub authentication
For production, replace the console.log SMS provider with a real SMS service like Unifonic, Taqnyat, or Msegat. See the SMS Provider API reference for integration examples.

Build docs developers (and LLMs) love