# Neon JS SDK - Auth Adapters Three adapters available for different API styles. **All adapters are factory functions that must be called with `()`.** ## BetterAuthVanillaAdapter (Default) Used automatically when no adapter is specified. Best for Node.js backends and non-React environments. ```typescript import { createClient } from "@neondatabase/neon-js"; // Default adapter - no need to specify const client = createClient({ auth: { url: process.env.NEON_AUTH_URL! }, dataApi: { url: process.env.NEON_DATA_API_URL! }, }); // Auth methods await client.auth.signIn.email({ email, password }); await client.auth.signUp.email({ email, password, name }); await client.auth.signOut(); const session = await client.auth.getSession(); // Social sign-in await client.auth.signIn.social({ provider: 'google', // or 'github' callbackURL: '/dashboard', }); ``` ## BetterAuthReactAdapter Provides React hooks for state management. **Must import from subpath.** ```typescript import { createClient } from "@neondatabase/neon-js"; // NOT exported from main entry - must use subpath import { BetterAuthReactAdapter } from "@neondatabase/neon-js/auth/react/adapters"; const client = createClient({ auth: { adapter: BetterAuthReactAdapter(), // Must call as function url: import.meta.env.VITE_NEON_AUTH_URL, }, dataApi: { url: import.meta.env.VITE_NEON_DATA_API_URL }, }); // React hook available function App() { const session = client.auth.useSession(); if (session.isPending) return
Loading...
; if (!session.data) return ; return ; } // Auth methods (same as vanilla) await client.auth.signIn.email({ email, password }); await client.auth.signUp.email({ email, password, name }); await client.auth.signOut(); ``` ## SupabaseAuthAdapter Provides Supabase-compatible API for easier migration. Exported from main entry. ```typescript import { createClient, SupabaseAuthAdapter } from "@neondatabase/neon-js"; const client = createClient({ auth: { adapter: SupabaseAuthAdapter(), // Must call as function url: process.env.NEON_AUTH_URL!, }, dataApi: { url: process.env.NEON_DATA_API_URL! }, }); // Supabase-compatible methods await client.auth.signInWithPassword({ email, password }); await client.auth.signUp({ email, password }); const { data: { session } } = await client.auth.getSession(); // Auth state change listener client.auth.onAuthStateChange((event, session) => { console.log('Auth event:', event); console.log('Session:', session); }); // Social sign-in (Supabase style) await client.auth.signInWithOAuth({ provider: 'google', options: { redirectTo: '/dashboard' }, }); ``` ## Adapter Comparison | Feature | BetterAuthVanilla | BetterAuthReact | SupabaseAuth | |---------|-------------------|-----------------|--------------| | React hooks | No | Yes | No | | Sign in method | `signIn.email()` | `signIn.email()` | `signInWithPassword()` | | Get session | `getSession()` | `getSession()` / `useSession()` | `getSession()` | | State listener | No | React state | `onAuthStateChange()` | | Bundle size | Smallest | Medium | Medium | | Best for | Node.js, SSR | React SPAs | Supabase migration | ## Supabase Migration Guide ### Step 1: Update imports ```diff - import { createClient } from "@supabase/supabase-js"; + import { createClient, SupabaseAuthAdapter } from "@neondatabase/neon-js"; ``` ### Step 2: Update client creation ```diff - const client = createClient(SUPABASE_URL, SUPABASE_KEY); + const client = createClient({ + auth: { adapter: SupabaseAuthAdapter(), url: NEON_AUTH_URL }, + dataApi: { url: NEON_DATA_API_URL }, + }); ``` ### Step 3: Auth methods work the same ```typescript // These work identically await client.auth.signInWithPassword({ email, password }); await client.auth.signUp({ email, password }); const { data: { session } } = await client.auth.getSession(); client.auth.onAuthStateChange((event, session) => { /* ... */ }); ``` ### Step 4: Database queries work the same ```typescript // PostgREST syntax is identical const { data } = await client.from("items").select("*"); await client.from("items").insert({ name: "Item" }); await client.from("items").update({ status: "done" }).eq("id", 1); await client.from("items").delete().eq("id", 1); ``` ## Common Adapter Mistakes ### 1. Forgetting to call adapter as function ```typescript // Wrong auth: { adapter: SupabaseAuthAdapter, url } // Correct auth: { adapter: SupabaseAuthAdapter(), url } ``` ### 2. Importing BetterAuthReactAdapter from main entry ```typescript // Wrong - not exported from main import { BetterAuthReactAdapter } from "@neondatabase/neon-js"; // Correct import { BetterAuthReactAdapter } from "@neondatabase/neon-js/auth/react/adapters"; ``` ### 3. Using wrong API for adapter ```typescript // Wrong - BetterAuth API with SupabaseAuthAdapter client.auth.signIn.email({ email, password }); // Won't work // Correct - Supabase API with SupabaseAuthAdapter client.auth.signInWithPassword({ email, password }); ``` ## Auth Only Package If you don't need database queries, use `@neondatabase/auth` for a smaller bundle: ```typescript // Install: npm install @neondatabase/auth import { createAuthClient } from "@neondatabase/auth"; import { BetterAuthReactAdapter } from "@neondatabase/auth/react/adapters"; // First arg is URL, second is config const auth = createAuthClient(import.meta.env.VITE_NEON_AUTH_URL, { adapter: BetterAuthReactAdapter(), }); // React hook const session = auth.useSession(); // Auth methods await auth.signIn.email({ email, password }); await auth.signUp.email({ email, password, name }); await auth.signOut(); ```