---
title: Migrate from Neon Auth SDK v0.1 to v0.2
subtitle: Upgrade guide for breaking changes in the Neon Auth SDK
enableTableOfContents: true
updatedOn: '2026-01-30T14:03:06.266Z'
---
This guide helps you migrate from Neon Auth SDK v0.1.x to v0.2.x, which introduces a unified API and performance improvements through session caching.
## What's new in v0.2
### Unified entry point
The SDK now uses a single `createNeonAuth()` function that replaces four separate imports:
- `neonAuth()` → `auth.getSession()`
- `authApiHandler()` → `auth.handler()`
- `neonAuthMiddleware()` → `auth.middleware()`
- `createAuthServer()` → `createNeonAuth()`
### Session caching
Session data is automatically cached in a signed cookie, reducing API calls to the Auth Server by 95-99%. Sessions are cached for 5 minutes by default (configurable).
### Explicit configuration
Configuration is now explicit rather than implicit. You must pass `baseUrl` and `cookies.secret` directly to `createNeonAuth()` instead of relying on automatic environment variable reading.
## Migration steps
### 1. Update package version
Update to the latest version:
```bash
npm install @neondatabase/auth@latest
```
### 2. Add required environment variable
Add `NEON_AUTH_COOKIE_SECRET` to your `.env` file. This secret is required for signing session data cookies:
```bash
# .env
NEON_AUTH_BASE_URL=https://ep-xxx.neonauth.us-east-1.aws.neon.tech/neondb/auth
NEON_AUTH_COOKIE_SECRET=your-secret-at-least-32-characters-long
```
Generate a secure secret with:
```bash
openssl rand -base64 32
```
The secret must be at least 32 characters for HMAC-SHA256 security.
### 3. Create unified auth instance
Create a new `lib/auth/server.ts` file with your auth configuration:
**Before (v0.1):**
```typescript
// lib/auth/server.ts
import { createAuthServer } from '@neondatabase/auth/next/server';
export const authServer = createAuthServer();
```
**After (v0.2):**
```typescript
// lib/auth/server.ts
import { createNeonAuth } from '@neondatabase/auth/next/server';
export const auth = createNeonAuth({
baseUrl: process.env.NEON_AUTH_BASE_URL!,
cookies: {
secret: process.env.NEON_AUTH_COOKIE_SECRET!,
},
});
```
The `auth` object provides all functionality: `handler()`, `middleware()`, `getSession()`, and all Better Auth server methods.
### 4. Update API route handler
**Before (v0.1):**
```typescript
// app/api/auth/[...path]/route.ts
import { authApiHandler } from '@neondatabase/auth/next/server';
export const { GET, POST } = authApiHandler();
```
**After (v0.2):**
```typescript
// app/api/auth/[...path]/route.ts
import { auth } from '@/lib/auth/server';
export const { GET, POST } = auth.handler();
```
### 5. Update middleware
**Before (v0.1):**
```typescript
// proxy.ts
import { neonAuthMiddleware } from '@neondatabase/auth/next/server';
export default neonAuthMiddleware({
loginUrl: '/auth/sign-in',
});
export const config = {
matcher: ['/account/:path*'],
};
```
**After (v0.2):**
```typescript
// proxy.ts
import { auth } from '@/lib/auth/server';
export default auth.middleware({
loginUrl: '/auth/sign-in',
});
export const config = {
matcher: ['/account/:path*'],
};
```
### 6. Update server components
**Before (v0.1):**
```typescript
// app/dashboard/page.tsx
import { neonAuth } from '@neondatabase/auth/next/server';
export default async function DashboardPage() {
const { session, user } = await neonAuth();
if (!user) {
return
Not logged in
;
}
return Hello {user.name}
;
}
```
**After (v0.2):**
```typescript
// app/dashboard/page.tsx
import { auth } from '@/lib/auth/server';
// Server components using auth methods must be rendered dynamically
export const dynamic = 'force-dynamic';
export default async function DashboardPage() {
const { data: session } = await auth.getSession();
if (!session?.user) {
return Not logged in
;
}
return Hello {session.user.name}
;
}
```
Server components that use `auth` methods must set `export const dynamic = 'force-dynamic'` because session data depends on cookies that can only be read at request time.
### 7. Update server actions
**Before (v0.1):**
```typescript
'use server';
import { authServer } from '@/lib/auth/server';
import { redirect } from 'next/navigation';
export async function signOut() {
await authServer.signOut();
redirect('/auth/sign-in');
}
```
**After (v0.2):**
```typescript
'use server';
import { auth } from '@/lib/auth/server';
import { redirect } from 'next/navigation';
export async function signOut() {
await auth.signOut();
redirect('/auth/sign-in');
}
```
All Better Auth server methods are available directly on the `auth` object: `signIn`, `signUp`, `signOut`, `updateUser`, `organization.*`, `admin.*`, etc.
### 8. Update API routes
**Before (v0.1):**
```typescript
// app/api/user/route.ts
import { authServer } from '@/lib/auth/server';
export async function GET() {
const { data } = await authServer.getSession();
if (!data?.session) {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
}
return Response.json({ user: data.user });
}
```
**After (v0.2):**
```typescript
// app/api/user/route.ts
import { auth } from '@/lib/auth/server';
export async function GET() {
const { data: session } = await auth.getSession();
if (!session?.user) {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
}
return Response.json({ user: session.user });
}
```
### 9. Client-side code (no changes)
Client-side code using `createAuthClient()` remains unchanged:
```typescript
// lib/auth/client.ts
'use client';
import { createAuthClient } from '@neondatabase/auth/next';
export const authClient = createAuthClient();
```
Client components and hooks work the same way:
```typescript
'use client';
import { authClient } from '@/lib/auth/client';
export function UserProfile() {
const { data } = authClient.useSession();
return {data?.user?.name}
;
}
```
## API changes reference
### Removed APIs
| v0.1 API | v0.2 Replacement |
| ---------------------- | ------------------- |
| `neonAuth()` | `auth.getSession()` |
| `authApiHandler()` | `auth.handler()` |
| `neonAuthMiddleware()` | `auth.middleware()` |
| `createAuthServer()` | `createNeonAuth()` |
### Return value changes
#### `getSession()` return format
**Before (v0.1):**
```typescript
const { session, user } = await neonAuth();
// Returns: { session: Session, user: User }
```
**After (v0.2):**
```typescript
const { data: session } = await auth.getSession();
// Returns: { data: { session: Session, user: User } | null, error: Error | null }
```
The new format is consistent with Better Auth's standard response pattern.
## Configuration options
The `createNeonAuth()` function accepts these configuration options:
```typescript
import { createNeonAuth } from '@neondatabase/auth/next/server';
export const auth = createNeonAuth({
baseUrl: process.env.NEON_AUTH_BASE_URL!,
cookies: {
secret: process.env.NEON_AUTH_COOKIE_SECRET!,
},
});
```
## Performance improvements
The v0.2 SDK includes automatic session caching that reduces API calls by 95-99%:
- Session data is cached in a signed cookie (`__Secure-neon-auth.next.session_data`)
- Cache is valid for 5 minutes by default (configurable via `sessionDataTtl`)
- Automatically refreshed when the session token is refreshed
- Falls back to API calls if cache is stale or missing
No code changes are needed to benefit from this caching. It works automatically after you configure `cookies.secret`.
## Troubleshooting
### Error: "Missing required config: cookies.secret"
You need to add `NEON_AUTH_COOKIE_SECRET` to your environment variables:
```bash
NEON_AUTH_COOKIE_SECRET=$(openssl rand -base64 32)
```
### Error: "Server Component functions should be marked with 'force-dynamic'"
Add this to any server component that uses auth methods:
```typescript
export const dynamic = 'force-dynamic';
```
### Session not persisting
Ensure your `NEON_AUTH_COOKIE_SECRET` is:
- At least 32 characters long
- The same across all environments
- Not changing between deployments
### TypeScript errors after upgrade
Run:
```bash
npm install @neondatabase/auth@latest
rm -rf node_modules/.cache
npm run dev
```
## Complete migration checklist
- [ ] Update `@neondatabase/auth` to v0.2.x
- [ ] Add `NEON_AUTH_COOKIE_SECRET` to `.env`
- [ ] Create `lib/auth/server.ts` with `createNeonAuth()`
- [ ] Update `app/api/auth/[...path]/route.ts` to use `auth.handler()`
- [ ] Update `proxy.ts` to use `auth.middleware()`
- [ ] Replace all `neonAuth()` calls with `auth.getSession()`
- [ ] Replace all `authServer` imports with `auth`
- [ ] Add `export const dynamic = 'force-dynamic'` to server components
- [ ] Update return value destructuring from `{ session, user }` to `{ data: session }`
- [ ] Test authentication flow in development
- [ ] Deploy with new environment variable
## Additional resources
- [Next.js Server SDK Reference](/docs/auth/reference/nextjs-server) - Complete API documentation
- [Neon Auth SDK Changelog](https://github.com/neondatabase/neon-js/blob/main/packages/auth/CHANGELOG.md#020-beta1)
- [Next.js Integration Guide](/docs/auth/quick-start/nextjs)
- [Neon Auth Overview](/docs/auth/overview)