If your Auth.js setup is working well there is no urgent need to migrate.
Better Auth continues to add features previously exclusive to Auth.js, and we
welcome the opportunity to earn your adoption on new or greenfield projects.
Create the Better Auth instance
Follow the installation guide to add Better Auth to your
project. Here is a side-by-side comparison of a minimal GitHub OAuth config:
- Auth.js
- Better Auth
auth.ts
Create the client instance
Better Auth ships a separate client package for browser/React usage:
auth-client.ts
Update the route handler
Rename
/app/api/auth/[...nextauth] to /app/api/auth/[...all], then
update route.ts:- Auth.js
- Better Auth
app/api/auth/[...nextauth]/route.ts
Protect routes
Better Auth recommends checking the session on each page or route rather
than relying on middleware for full authorization.
- Server component
- Client component
app/dashboard/page.tsx
Migrate the database
If you were using the Auth.js database session strategy you will need to
migrate your data. The table below summarises the schema differences.
User table
| Field | Auth.js | Better Auth |
|---|---|---|
name | optional | required |
email | optional | required, unique |
emailVerified | Date | null | boolean |
createdAt | — | Date |
updatedAt | — | Date |
Session table
| Field | Auth.js | Better Auth |
|---|---|---|
sessionToken | ✓ | renamed to token |
expires | Date | renamed to expiresAt |
ipAddress | — | string | null |
userAgent | — | string | null |
createdAt | — | Date |
updatedAt | — | Date |
Account table
| Field | Auth.js | Better Auth |
|---|---|---|
provider | ✓ | renamed to providerId |
providerAccountId | ✓ | renamed to accountId |
refresh_token | snake_case | refreshToken (camelCase) |
access_token | snake_case | accessToken (camelCase) |
expires_at | number | accessTokenExpiresAt: Date |
type | ✓ | removed (derived from providerId) |
password | — | added for credential accounts |
VerificationToken → Verification
| Field | Auth.js | Better Auth |
|---|---|---|
composite PK (identifier, token) | ✓ | replaced by id: string |
token | ✓ | renamed to value |
expires | Date | renamed to expiresAt |
createdAt | — | Date |
updatedAt | — | Date |