# @neondatabase/auth-ui

> React UI components for Neon Auth - pre-built sign-in, sign-up, and user management forms

Latest version **0.4.0-beta** (published 2026-10-12) · Apache-2.0 license · 0 weekly downloads

## Install

```sh
npm install @neondatabase/auth-ui
pnpm add @neondatabase/auth-ui
yarn add @neondatabase/auth-ui
bun add @neondatabase/auth-ui
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score; high quality score.

Warnings: low downloads; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.4.0-beta |
| Published | 2026-10-12 |
| First published | 2025-12-07 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 38 |
| Unpacked size | 810.1 KB |
| Known vulnerabilities | 0 (+4 in 2 direct dependencies) |
| Install scripts | no |
| GitHub stars | 19 |
| Author | Pedro Figueiredo |
| Maintainers | jawj, amitdahan, pffigueiredo, shridharneon, atilaz, neonteam |
| Keywords | neon, neondb, authentication, auth, ui, components, react, typescript, sign-in, sign-up, better-auth, tailwindcss |

## Links

- npm: https://www.npmjs.com/package/@neondatabase/auth-ui
- Repository: https://github.com/neondatabase/neon-js
- Homepage: https://github.com/neondatabase/neon-js/tree/main/packages/auth-ui#readme
- Issues: https://github.com/neondatabase/neon-js/issues
- Funding: https://neon.tech
- npm.io page: https://npm.io/package/@neondatabase/auth-ui

## Dependencies (38)

- [zod](https://npm.io/package/zod.md) 4.5.4
- [clsx](https://npm.io/package/clsx.md) ^2.1.1
- [vaul](https://npm.io/package/vaul.md) ^1.1.2
- [sonner](https://npm.io/package/sonner.md) ^2.0.7
- [input-otp](https://npm.io/package/input-otp.md) ^1.4.2
- [better-auth](https://npm.io/package/better-auth.md) 1.7.6
- [better-call](https://npm.io/package/better-call.md) 1.4.0
- [next-themes](https://npm.io/package/next-themes.md) ^0.4.6
- [tailwindcss](https://npm.io/package/tailwindcss.md) 4.2.1
- [lucide-react](https://npm.io/package/lucide-react.md) ^0.555.0
- [ua-parser-js](https://npm.io/package/ua-parser-js.md) ^2.0.9
- [react-qr-code](https://npm.io/package/react-qr-code.md) ^2.0.18
- [tailwind-merge](https://npm.io/package/tailwind-merge.md) ^3.4.0
- [tw-animate-css](https://npm.io/package/tw-animate-css.md) ^1.4.0
- [react-hook-form](https://npm.io/package/react-hook-form.md) ^7.66.1
- [@captchafox/react](https://npm.io/package/@captchafox/react.md) ^1.10.0
- [@better-auth/utils](https://npm.io/package/@better-auth/utils.md) 0.4.2
- [@hookform/resolvers](https://npm.io/package/@hookform/resolvers.md) ^5.2.2
- [@better-auth/passkey](https://npm.io/package/@better-auth/passkey.md) 1.7.6
- [@radix-ui/react-slot](https://npm.io/package/@radix-ui/react-slot.md) ^1.2.4
- [@radix-ui/react-tabs](https://npm.io/package/@radix-ui/react-tabs.md) ^1.1.13
- [@radix-ui/react-label](https://npm.io/package/@radix-ui/react-label.md) ^2.1.8
- [@radix-ui/react-avatar](https://npm.io/package/@radix-ui/react-avatar.md) ^1.1.11
- [@radix-ui/react-dialog](https://npm.io/package/@radix-ui/react-dialog.md) ^1.1.15
- [@radix-ui/react-select](https://npm.io/package/@radix-ui/react-select.md) ^2.2.6
- [react-google-recaptcha](https://npm.io/package/react-google-recaptcha.md) ^3.1.0
- [@radix-ui/react-context](https://npm.io/package/@radix-ui/react-context.md) ^1.1.3
- [@hcaptcha/react-hcaptcha](https://npm.io/package/@hcaptcha/react-hcaptcha.md) ^1.12.1
- [@radix-ui/react-checkbox](https://npm.io/package/@radix-ui/react-checkbox.md) ^1.3.3
- [class-variance-authority](https://npm.io/package/class-variance-authority.md) ^0.7.1
- [@marsidev/react-turnstile](https://npm.io/package/@marsidev/react-turnstile.md) ^1.1.0
- [@radix-ui/react-primitive](https://npm.io/package/@radix-ui/react-primitive.md) ^2.1.4
- [@radix-ui/react-separator](https://npm.io/package/@radix-ui/react-separator.md) ^1.1.8
- [@daveyplate/better-auth-ui](https://npm.io/package/@daveyplate/better-auth-ui.md) 3.4.0
- [@radix-ui/react-dropdown-menu](https://npm.io/package/@radix-ui/react-dropdown-menu.md) ^2.1.16
- [@wojtekmaj/react-recaptcha-v3](https://npm.io/package/@wojtekmaj/react-recaptcha-v3.md) ^0.1.4
- [@radix-ui/react-use-callback-ref](https://npm.io/package/@radix-ui/react-use-callback-ref.md) ^1.1.1
- [@radix-ui/react-use-layout-effect](https://npm.io/package/@radix-ui/react-use-layout-effect.md) ^1.1.1

## Alternatives

- [@pothos/plugin-authz](https://npm.io/package/@pothos/plugin-authz.md) — 12.4K weekly downloads
- [@bounded-sh/client](https://npm.io/package/@bounded-sh/client.md) — 3.2K weekly downloads
- [@luigi-project/plugin-auth-oauth2](https://npm.io/package/@luigi-project/plugin-auth-oauth2.md) — 2.3K weekly downloads
- [@nocobase/plugin-verification](https://npm.io/package/@nocobase/plugin-verification.md) — 2.0K weekly downloads
- [escher-request](https://npm.io/package/escher-request.md) — 545 weekly downloads

## Recent versions

- 0.4.0-beta (latest) — 2026-10-12
- 0.3.0-beta — 2026-08-11
- 0.2.1-beta — 2026-06-08
- 0.2.0-beta — 2026-04-29
- 0.1.0-alpha.11 — 2026-01-14
- 0.1.0-alpha.10 — 2025-12-11
- 0.1.0-alpha.9 — 2025-12-09
- 0.1.0-alpha.8 — 2025-12-09
- 0.1.0-alpha.7 — 2025-12-09
- 0.1.0-alpha.6 — 2025-12-09
- 0.1.0-alpha.5 — 2025-12-09
- 0.1.0-alpha.4 — 2025-12-09
- 0.1.0-alpha.3 — 2025-12-07

## README

# @neondatabase/auth-ui

[![npm version](https://img.shields.io/npm/v/@neondatabase/auth-ui.svg)](https://www.npmjs.com/package/@neondatabase/auth-ui)
[![npm downloads](https://img.shields.io/npm/dm/@neondatabase/auth-ui.svg)](https://www.npmjs.com/package/@neondatabase/auth-ui)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.0%2B-blue.svg)](https://www.typescriptlang.org/)
[![License](https://img.shields.io/npm/l/@neondatabase/auth-ui.svg)](https://github.com/neondatabase/neon-js/blob/main/LICENSE)

UI components for Neon Auth built on top of [better-auth-ui](https://better-auth-ui.com).

## Installation

```bash
npm install @neondatabase/auth-ui
# or
bun add @neondatabase/auth-ui
```

## Usage

### 1. Import the CSS

Choose the import method based on your project setup:

#### Option A: Without Tailwind CSS (recommended for most users)

If your project doesn't use Tailwind CSS, import the pre-built CSS bundle:

```typescript
// In your root layout or app entry point
import '@neondatabase/auth-ui/css';
```

This includes all necessary styles (~47KB minified) with no additional configuration required.

#### Option B: With Tailwind CSS

If your project already uses Tailwind CSS v4, import the Tailwind-ready CSS to avoid duplicate styles:

```css
/* In your main CSS file (e.g., globals.css, app.css) */
@import 'tailwindcss';
@import '@neondatabase/auth-ui/tailwind';
```

This imports only the theme variables and component scanning directive. Your Tailwind build will generate the necessary utility classes, avoiding duplication with your existing Tailwind setup.

### 2. Use the Provider

The `NeonAuthUIProvider` accepts all props from `@daveyplate/better-auth-ui`'s `AuthUIProvider`, plus:

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `authClient` | `NeonAuthPublicApi` | required | Auth client from `@neondatabase/auth` |
| `className` | `string` | - | Additional classes for the wrapper div |
| `defaultTheme` | `'light' \| 'dark' \| 'system'` | `'system'` | Default theme for next-themes |

#### With Next.js (Recommended)

```typescript
// lib/auth-client.ts
"use client"

import { createAuthClient } from "@neondatabase/auth/next"

export const authClient = createAuthClient()
```

```typescript
// app/providers.tsx
"use client"

import { NeonAuthUIProvider } from "@neondatabase/auth-ui"
import Link from "next/link"
import { useRouter } from "next/navigation"

import { authClient } from "@/lib/auth-client"

export function Providers({ children }: { children: React.ReactNode }) {
  const router = useRouter()

  return (
    <NeonAuthUIProvider
      authClient={authClient}
      navigate={router.push}
      replace={router.replace}
      onSessionChange={() => router.refresh()}
      emailOTP
      social={{ providers: ["google"] }}
      redirectTo="/dashboard"
      Link={Link}
      organization={{}}
    >
      {children}
    </NeonAuthUIProvider>
  )
}
```

#### With Other Frameworks

```typescript
"use client"

import { NeonAuthUIProvider } from "@neondatabase/auth-ui"
import { createAuthClient } from "@neondatabase/auth"

const authClient = createAuthClient(process.env.NEXT_PUBLIC_AUTH_URL!)

export function AuthProvider({ children }: { children: React.ReactNode }) {
  return (
    <NeonAuthUIProvider authClient={authClient}>
      {children}
    </NeonAuthUIProvider>
  )
}
```

### 3. Use Components

All components from `@daveyplate/better-auth-ui` are re-exported:

```typescript
import { 
  SignInForm, 
  SignUpForm, 
  UserButton,
  // ... all other components
} from '@neondatabase/auth-ui';
```

## Features

- ✅ **Works with or without Tailwind CSS** - Pre-built CSS bundle or Tailwind-ready import
- ✅ **Theme-safe** - Never overrides your custom CSS variables (uses fallback pattern)
- ✅ **Automatic React adapter** - Works with both vanilla and React Better Auth clients
- ✅ **Full better-auth-ui compatibility** - All components and utilities re-exported
- ✅ **Type-safe** - Full TypeScript support
- ✅ **Dark mode support** - Built-in next-themes integration

## CSS Exports

| Export | Size | Use Case |
|--------|------|----------|
| `@neondatabase/auth-ui/css` | ~47KB | Projects without Tailwind |
| `@neondatabase/auth-ui/tailwind` | ~3KB | Projects with Tailwind CSS v4 |

> **Note:** Deprecated compatibility CSS exports also exist under `@neondatabase/auth/ui/*`
> and `@neondatabase/neon-js/ui/*`. Prefer importing styles directly from
> `@neondatabase/auth-ui`; the compatibility exports will be removed in the next major version.

## Example (Next.js App Router)

### Without Tailwind

**app/layout.tsx**
```typescript
import '@neondatabase/auth-ui/css';
import { AuthProvider } from './auth-provider';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <AuthProvider>
          {children}
        </AuthProvider>
      </body>
    </html>
  );
}
```

### With Tailwind CSS

**app/globals.css**
```css
@import 'tailwindcss';
@import '@neondatabase/auth-ui/tailwind';

/* Your custom styles... */
```

**app/layout.tsx**
```typescript
import './globals.css';
import { AuthProvider } from './auth-provider';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <AuthProvider>
          {children}
        </AuthProvider>
      </body>
    </html>
  );
}
```

### Provider Setup

**lib/auth-client.ts**
```typescript
"use client"

import { createAuthClient } from "@neondatabase/auth/next"

export const authClient = createAuthClient()
```

**app/providers.tsx**
```typescript
"use client"

import { NeonAuthUIProvider } from "@neondatabase/auth-ui"
import Link from "next/link"
import { useRouter } from "next/navigation"

import { authClient } from "@/lib/auth-client"

export function Providers({ children }: { children: React.ReactNode }) {
  const router = useRouter()

  return (
    <NeonAuthUIProvider
      authClient={authClient}
      navigate={router.push}
      replace={router.replace}
      onSessionChange={() => router.refresh()}
      emailOTP
      social={{ providers: ["google"] }}
      redirectTo="/dashboard"
      Link={Link}
      organization={{}}
    >
      {children}
    </NeonAuthUIProvider>
  )
}
```

### Using Components

**app/auth/[path]/page.tsx**
```typescript
import { AuthView } from "@neondatabase/auth-ui"
import { authViewPaths } from "@neondatabase/auth-ui/server"

export const dynamicParams = false

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 (
    <main className="container flex grow flex-col items-center justify-center p-4">
      <AuthView path={path} />
    </main>
  )
}
```

## Customizing Theme

Neon Auth UI uses CSS custom properties for theming. **Your existing theme variables are respected** - auth-ui uses a fallback pattern that won't override your custom styles.

### How It Works

Auth-UI defines `--neon-*` prefixed variables on `:root` inside `@layer neon-auth`:
```css
--neon-primary: var(--primary, oklch(0.205 0 0));
```

This means:
1. If you define `--primary` in `:root`, auth-ui uses YOUR value
2. If you don't, auth-ui uses its default

### Core Color Tokens

Override in `:root` (light) and `.dark` (dark mode):

```css
:root {
  /* Primary - buttons, links, focus rings */
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);

  /* Secondary - secondary buttons */
  --secondary: oklch(0.97 0 0);
  --secondary-foreground: oklch(0.205 0 0);

  /* Background/Foreground - page colors */
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);

  /* Muted - placeholders, disabled states */
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);

  /* Accent - hover states */
  --accent: oklch(0.97 0 0);
  --accent-foreground: oklch(0.205 0 0);

  /* Destructive - errors, delete actions */
  --destructive: oklch(0.577 0.245 27.325);

  /* UI Elements */
  --border: oklch(0.922 0 0);
  --input: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);
  --radius: 0.625rem;
}

.dark {
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  /* ... other dark tokens */
}
```

### Token Pairing Rules

**CRITICAL:** Always override pairs together to maintain contrast.

| Background Token | Foreground Token | Min Contrast |
|-----------------|------------------|--------------|
| `--primary` | `--primary-foreground` | 4.5:1 |
| `--secondary` | `--secondary-foreground` | 4.5:1 |
| `--background` | `--foreground` | 4.5:1 |
| `--muted` | `--muted-foreground` | 4.5:1 |
| `--accent` | `--accent-foreground` | 4.5:1 |
| `--destructive` | `--destructive-foreground` | 4.5:1 |

### OKLCH Color Format

Format: `oklch(L C H)` or `oklch(L C H / alpha)`

| Parameter | Range | Description |
|-----------|-------|-------------|
| L (Lightness) | 0-1 | 0 = black, 1 = white |
| C (Chroma) | 0-0.4 | 0 = gray, higher = more vivid |
| H (Hue) | 0-360 | Color wheel degrees |
| alpha | 0-1 | Opacity |

**Convert HEX/RGB to OKLCH:** https://oklch.com

### Dark Mode Implementation

`NeonAuthUIProvider` includes next-themes by default. Control the initial theme with the `defaultTheme` prop:

```typescript
<NeonAuthUIProvider
  authClient={authClient}
  defaultTheme="dark"  // 'light' | 'dark' | 'system'
>
  {children}
</NeonAuthUIProvider>
```

#### CSS Only (System Preference)

```css
@media (prefers-color-scheme: dark) {
  :root {
    --background: oklch(0.145 0 0);
    --foreground: oklch(0.985 0 0);
  }
}
```

### Component-Specific Styling

All UI components accept `classNames` props:

```typescript
<SignInForm
  className="mx-auto max-w-md"
  classNames={{
    card: "border-primary/20",
    button: "rounded-full",
    input: "bg-muted/50",
  }}
/>
```

Available interfaces: `AuthViewClassNames`, `AuthFormClassNames`, `UserAvatarClassNames`, `UserButtonClassNames`, `SettingsCardClassNames`

## Documentation

For component documentation, see the [better-auth-ui docs](https://better-auth-ui.com).

## Related Packages

- [`@neondatabase/auth`](../auth) - Authentication adapters for Neon Auth
- [`@neondatabase/neon-js`](../neon-js) - Full SDK with database and auth integration

## Support

- [GitHub Issues](https://github.com/neondatabase/neon-js/issues)
- [Neon Community Discord](https://discord.gg/H24eC2UN)

## License

Apache-2.0

---
_Source: https://npm.io/package/@neondatabase/auth-ui · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
