This 250+ engineer team replaced shared staging with isolated database branches for safer deploys
/AI for Agents/Neon Auth

AI Rules: Neon Auth

Context rules for AI tools to help implement authentication with Stack Auth and Neon databases

Related docs

How to use

You can use these rules in two ways:

  1. Option 1: Copy from this page

    With Cursor, save the rules to .cursor/rules/neon-auth.mdc and they'll be automatically applied when working with matching files (*.ts, *.tsx).

    For other AI tools, you can include these rules as context when chatting with your AI assistant - check your tool's documentation for the specific method (like using "Include file" or context commands).

  2. Option 2: Clone from repository

    If you prefer, you can clone or download the rules directly from our AI Rules repository.

    Once added to your project, AI tools will automatically use these rules when working with Neon Auth code. You can also reference them explicitly in prompts.

Rules

---
description: Use these rules when implementing authentication with @neondatabase/auth or @neondatabase/neon-js
globs: *.tsx, *.ts
alwaysApply: false
---
# Neon Auth Guidelines

> **For AI Agents with file access (Claude Code, etc.):**
> For complete documentation without summarization, fetch references using:
> ```bash
> curl -s -o /tmp/neon-auth-setup.md https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-setup-nextjs.md
> ```
> Then read the downloaded file. Replace `nextjs` with `react-spa` or `nodejs` as needed.

## Overview

Neon Auth provides authentication for your application. It's available as:
- `@neondatabase/auth` - Auth only (smaller bundle)
- `@neondatabase/neon-js` - Auth + Data API (full SDK)

## Package Selection

| Need | Package | Bundle |
|------|---------|--------|
| Auth only | `@neondatabase/auth` | Smaller |
| Auth + Database queries | `@neondatabase/neon-js` | Full |

## Installation

```bash
# Auth only
npm install @neondatabase/auth

# Auth + Data API
npm install @neondatabase/neon-js
```

## Quick Setup Patterns

### Next.js App Router

**1. API Route Handler:**
```typescript
// app/api/auth/[...path]/route.ts
import { authApiHandler } from "@neondatabase/auth/next";
export const { GET, POST } = authApiHandler();
```

**2. Auth Client:**
```typescript
// lib/auth/client.ts
import { createAuthClient } from "@neondatabase/auth/next";
export const authClient = createAuthClient();
```

**3. Use in Components:**
```typescript
"use client";
import { authClient } from "@/lib/auth/client";

function AuthStatus() {
  const session = authClient.useSession();
  if (session.isPending) return <div>Loading...</div>;
  if (!session.data) return <SignInButton />;
  return <div>Hello, {session.data.user.name}</div>;
}
```

**Complete setup:** See [Setup Reference - Next.js](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-setup-nextjs.md)

### React SPA

```typescript
import { createAuthClient } from "@neondatabase/auth";
import { BetterAuthReactAdapter } from "@neondatabase/auth/react/adapters";

const authClient = createAuthClient(
  import.meta.env.VITE_NEON_AUTH_URL,
  { adapter: BetterAuthReactAdapter() }
);
```

**Complete setup with router:** See [Setup Reference - React SPA](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-setup-react-spa.md)

### Node.js Backend

```typescript
import { createAuthClient } from "@neondatabase/auth";

const auth = createAuthClient(process.env.NEON_AUTH_URL!);
await auth.signIn.email({ email, password });
const session = await auth.getSession();
```

**Complete setup:** See [Setup Reference - Node.js](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-setup-nodejs.md)

## Building Auth Pages

### Use AuthView (Recommended for React Apps)

For authentication pages, use the pre-built `AuthView` component instead of building custom forms.

**What AuthView provides:**
- Sign-in, sign-up, password reset, magic link pages
- Social providers (Google, GitHub) - requires TWO configurations: enable in Neon Console AND add `social` prop to NeonAuthUIProvider
- Form validation, error handling, loading states
- Consistent styling via CSS variables

**Setup (Next.js App Router):**

1. **Import CSS** (in `app/layout.tsx` or `app/globals.css`):
```tsx
import "@neondatabase/auth/ui/css";
```

2. **Wrap app with provider** (create `app/auth-provider.tsx`):
```tsx
"use client";
import { NeonAuthUIProvider } from "@neondatabase/auth/react/ui";
import { authClient } from "@/lib/auth/client";
import { useRouter } from "next/navigation";
import Link from "next/link";

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const router = useRouter();
  return (
    <NeonAuthUIProvider
      authClient={authClient}
      navigate={router.push}
      replace={router.replace}
      onSessionChange={() => router.refresh()}
      Link={Link}
    >
      {children}
    </NeonAuthUIProvider>
  );
}
```

3. **Create auth page** (`app/auth/[path]/page.tsx`):
```tsx
import { AuthView } from "@neondatabase/auth/react/ui";
import { authViewPaths } from "@neondatabase/auth/react/ui/server";

export function generateStaticParams() {
  return Object.values(authViewPaths).map((path) => ({ path }));
}

export default async function AuthPage({
  params,
}: {
  params: Promise<{ path: string }>;
}) {
  const { path } = await params;
  return <AuthView pathname={path} />;
}
```

**Result:** You now have `/auth/sign-in`, `/auth/sign-up`, `/auth/forgot-password`, etc.

**Available paths:** `"sign-in"`, `"sign-up"`, `"forgot-password"`, `"reset-password"`, `"magic-link"`, `"two-factor"`, `"callback"`, `"sign-out"`

**For React SPA setup:** See [UI Components Reference - React SPA](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-ui-react-spa.md)

### When to Use Low-Level Methods Instead

Use `authClient.signIn.email()`, `authClient.signUp.email()` directly if:

- **Node.js backend** - No React, server-side auth only
- **Custom design system** - Your design team provides form components
- **Mobile/CLI apps** - Non-web frontends
- **Headless auth** - Testing or non-standard flows

For standard React web apps, **use AuthView**.

### Common Anti-Pattern

```tsx
// ❌ Don't build custom forms unless you have specific requirements
function CustomSignInPage() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(false);

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);
    const { error } = await authClient.signIn.email({ email, password });
    if (error) setError(error.message);
    setLoading(false);
  };

  // ... 50+ more lines of form JSX, validation, error display
}

// ✅ Use AuthView instead - one component handles everything
<AuthView pathname="sign-in" />
```

## Environment Variables

```bash
# Next.js (.env.local)
NEON_AUTH_BASE_URL=https://ep-xxx.neonauth.c-2.us-east-2.aws.neon.build/dbname/auth
NEXT_PUBLIC_NEON_AUTH_URL=https://ep-xxx.neonauth.c-2.us-east-2.aws.neon.build/dbname/auth

# Vite/React (.env)
VITE_NEON_AUTH_URL=https://ep-xxx.neonauth.c-2.us-east-2.aws.neon.build/dbname/auth
```

**Complete reference:** See framework-specific setup guides above for environment variable details.

## Auth Methods

> **For React apps:** Consider using `AuthView` instead of building custom forms - see [Building Auth Pages](#building-auth-pages) above. The methods below are for Node.js backends, custom design systems, or non-React frontends.

### Sign Up
```typescript
await auth.signUp.email({
  email: "user@example.com",
  password: "securepassword",
  name: "John Doe", // Optional
});
```

### Sign In
```typescript
// Email/password
await auth.signIn.email({
  email: "user@example.com",
  password: "securepassword",
});

// Social (Google, GitHub)
await auth.signIn.social({
  provider: "google", // or "github"
  callbackURL: "/dashboard",
});
```

### Sign Out
```typescript
await auth.signOut();
```

### Get Session
```typescript
// Async (Node.js, server components)
const session = await auth.getSession();

// React hook (client components)
const session = auth.useSession();
// Returns: { data: Session | null, isPending: boolean }
```

### Session Data Structure
```typescript
interface Session {
  user: {
    id: string;
    name: string | null;
    email: string;
    image: string | null;
    emailVerified: boolean;
    createdAt: Date;
    updatedAt: Date;
  };
  session: {
    id: string;
    expiresAt: Date;
    token: string;
    createdAt: Date;
    updatedAt: Date;
    userId: string;
  };
}
```

## UI Components

For pre-built UI components, see [Building Auth Pages](#building-auth-pages) above.

**Available components:**
- `AuthView` - Complete auth pages (sign-in, sign-up, forgot-password, etc.) - **use this first**
- `SignedIn` / `SignedOut` - Conditional rendering based on auth state
- `UserButton` - User avatar with dropdown menu
- `NeonAuthUIProvider` - Required wrapper for UI components

**Complete UI reference:** See [UI Components Reference - Next.js](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-ui-nextjs.md) or [React SPA](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-ui-react-spa.md)

## React Styling Guidelines

**CRITICAL:** When creating React components, always use existing CSS variables. Do NOT create new colors or style values.

### Use Existing CSS Variables

The UI package provides all necessary CSS variables. Always use these variables in your custom components (navbar, layouts, pages, etc.):

| Variable | Purpose | Usage |
|----------|---------|-------|
| `--background`, `--foreground` | Page background/text | `hsl(var(--background))` |
| `--card`, `--card-foreground` | Card surfaces | `hsl(var(--card))` |
| `--primary`, `--primary-foreground` | Primary buttons/actions | `hsl(var(--primary))` |
| `--secondary`, `--secondary-foreground` | Secondary elements | `hsl(var(--secondary))` |
| `--muted`, `--muted-foreground` | Muted/subtle elements | `hsl(var(--muted))` |
| `--destructive` | Destructive/danger actions | `hsl(var(--destructive))` |
| `--border`, `--input`, `--ring` | Borders and focus rings | `hsl(var(--border))` |
| `--radius` | Border radius | `var(--radius)` |

### Examples

**✅ Correct - Uses CSS variables:**
```tsx
<div style={{ background: 'hsl(var(--background))', color: 'hsl(var(--foreground))' }}>
  <button style={{ background: 'hsl(var(--primary))', color: 'hsl(var(--primary-foreground))' }}>
    Submit
  </button>
</div>
```

**❌ Wrong - Creates new colors:**
```tsx
<div style={{ background: '#ffffff', color: '#000000' }}>
  <button style={{ background: '#3b82f6', color: '#ffffff' }}>
    Submit
  </button>
</div>
```

**Why:** Using CSS variables ensures:
- Visual consistency with auth components
- Automatic dark mode support
- Proper theming integration
- No duplicate color definitions

**Complete theming guide:** See [UI Theming Guide](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-js-theming.md)

## Key Imports

```typescript
// Auth client (Next.js)
import { authApiHandler, createAuthClient } from "@neondatabase/auth/next";

// Auth client (vanilla)
import { createAuthClient } from "@neondatabase/auth";

// React adapter (NOT from main entry)
import { BetterAuthReactAdapter } from "@neondatabase/auth/react/adapters";

// UI components
import { NeonAuthUIProvider, AuthView, SignInForm } from "@neondatabase/auth/react/ui";
import { authViewPaths } from "@neondatabase/auth/react/ui/server";

// CSS
import "@neondatabase/auth/ui/css";
```

**Complete import reference:** See [Import Reference](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-js-imports.md)

## Common Mistakes

> **Full Reference:** See [Common Mistakes Guide](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-common-mistakes.md) for detailed solutions.

**Quick Summary:**

1. **Wrong adapter import**: Import `BetterAuthReactAdapter` from `auth/react/adapters` subpath
2. **Forgetting to call adapter**: Use `BetterAuthReactAdapter()` with parentheses
3. **Missing CSS**: Import from `ui/css` or `ui/tailwind` (not both)
4. **Missing "use client"**: Required for components using `useSession()`
5. **Wrong createAuthClient signature**: First arg is URL: `createAuthClient(url, { adapter })`
6. **Building custom sign-in/sign-up forms unnecessarily**: Before building forms with `signIn.email()`, check if `AuthView` meets your needs - it handles validation, errors, social providers, and loading states automatically.

**Code generation rules:** See [Code Generation Rules](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/code-generation-rules.md)

## Error Handling

```typescript
const { error } = await auth.signIn.email({ email, password });

if (error) {
  switch (error.code) {
    case "INVALID_EMAIL_OR_PASSWORD":
      showError("Invalid email or password");
      break;
    case "EMAIL_NOT_VERIFIED":
      showError("Please verify your email");
      break;
    case "USER_NOT_FOUND":
      showError("User not found");
      break;
    case "TOO_MANY_REQUESTS":
      showError("Too many attempts. Please wait.");
      break;
    default:
      showError("Authentication failed");
  }
}
```

## References

### Framework-Specific Setup (choose your framework)
- [Setup - Next.js](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-setup-nextjs.md) - Next.js App Router setup
- [Setup - React SPA](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-setup-react-spa.md) - Vite/CRA setup
- [Setup - Node.js](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-setup-nodejs.md) - Backend-only setup

### Framework-Specific UI (choose your framework)
- [UI - Next.js](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-ui-nextjs.md) - Next.js UI provider
- [UI - React SPA](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-ui-react-spa.md) - React SPA UI provider

### Shared References
- [Common Mistakes](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-common-mistakes.md) - Import paths, adapter patterns, CSS
- [Troubleshooting Guide](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-auth-troubleshooting.md) - Error solutions
- [Code Generation Rules](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/code-generation-rules.md) - Import and CSS strategies
- [Auth Adapters Guide](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-js-adapters.md) - Adapter comparison
- [Import Reference](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-js-imports.md) - Complete import paths
- [UI Theming Guide](https://raw.githubusercontent.com/neondatabase-labs/ai-rules/main/references/neon-js-theming.md) - Styling options
- For database queries with auth, see **neon-js.mdc**

Last updated on

Was this page helpful?