The Neon TypeScript SDK (@neondatabase/neon-js) provides authentication and database operations for your applications.

Authentication is provided through an adapter-based architecture, letting you work more easily with your existing code or preferred framework. Available adapters:

  • BetterAuthVanillaAdapter (default) — Promise-based authentication methods like client.auth.signIn.email(). Used in all examples on this page.
  • BetterAuthReactAdapter — Similar API but with React hooks like useSession(). See the React quickstart.
  • SupabaseAuthAdapter — Supabase-compatible API for easy migration. See the migration guide.

Database query methods (client.from(), .select(), etc.) work the same regardless of which adapter you use.

  1. Installation

    Install the TypeScript SDK in your project using npm, yarn, pnpm, or bun.

    npm install @neondatabase/neon-js
  2. Initialize the client

    createClient()createAuthClient()

    Full client (createClient)

    Use this when you need both authentication and database queries. You get:

    • Auth methods like client.auth.signIn.email() and client.auth.signUp.email().
    • Database queries like client.from('todos').select() and client.from('users').insert().

    Auth-only client (createAuthClient)

    Use this when you only need authentication (no database queries). You get:

    • Auth methods like auth.signIn.email() and auth.signUp.email()
    • No database query methods

    The auth methods are identical—only the access path differs. client.auth.signIn.email() and auth.signIn.email() do the same thing.

    Full client
    Auth-only
    With TypeScript types
    With a different adapter
    import { createClient } from '@neondatabase/neon-js';
    
    const client = createClient({
      auth: {
        url: import.meta.env.VITE_NEON_AUTH_URL,
      },
      dataApi: {
        url: import.meta.env.VITE_NEON_DATA_API_URL,
      },
    });
  3. Create a new user account

    auth.signUp.email()
    • Returns user and session data on success
    • User data is stored in your database
    • Sessions are managed automatically

    Parameters

    View parameters
    ParameterTypeRequired
    emailstring✓
    namestring✓
    passwordstring✓
    imagestring | undefined
    callbackURLstring | undefined
    const result = await client.auth.signUp.email({
      email: 'user@example.com',
      password: 'password123',
      name: 'John Doe'
    })
    
    if (result.error) {
    console.error('Sign up error:', result.error.message)
    } else {
    console.log('User created:', result.data.user)
    }
  4. Sign in with email and password

    auth.signIn.email()
    • Returns user and session on success
    • Session tokens are cached automatically
    • Authentication state syncs across browser tabs

    Parameters

    View parameters
    ParameterTypeRequired
    emailstring✓
    passwordstring✓
    rememberMeboolean | undefined
    callbackURLstring | undefined
    const result = await client.auth.signIn.email({
      email: 'user@example.com',
      password: 'password123'
    })
    
    if (result.error) {
    console.error('Sign in error:', result.error.message)
    } else {
    console.log('Signed in:', result.data.user.email)
    }
  5. Sign in with OAuth provider

    auth.signIn.social()

    Sign in with an OAuth provider like Google, GitHub, etc.

    • Redirects user to provider's authorization page
    • User is redirected back after authorization
    • Session is created automatically

    Parameters

    View parameters
    ParameterTypeRequired
    providerstring✓
    callbackURLstring | undefined
    newUserCallbackURLstring | undefined
    errorCallbackURLstring | undefined
    disableRedirectboolean | undefined
    idTokenobject
    scopesstring[] | undefined
    requestSignUpboolean | undefined
    loginHintstring | undefined
    additionalDataobject
    Sign in with GitHub
    Sign in with custom redirect
    await client.auth.signIn.social({
      provider: 'github',
      callbackURL: 'https://yourapp.com/auth/callback',
    });
  6. Sign out

    auth.signOut()
    • Clears local session cache
    • Notifies other browser tabs (cross-tab sync)
    • Removes authentication tokens
    const { error } = await client.auth.signOut()
    
    if (error) {
    console.error('Sign out error:', error.message)
    }
  7. Get current session

    auth.getSession()
    • Returns cached session if available (fast)
    • Automatically refreshes expired tokens
    • Returns null if no active session
    const { data, error } = await client.auth.getSession()
    
    if (data.session) {
    console.log('User is logged in:', data.session.user.email)
    } else {
    console.log('No active session')
    }
  8. Update user profile

    auth.updateUser()

    Note: Password updates require password reset flow for security.

    Parameters

    View parameters
    ParameterTypeRequired
    namestring | undefined
    imagestring | null | undefined
    const { data, error } = await client.auth.updateUser({
      name: 'New Name'
    })
  9. Send verification OTP code

    auth.emailOtp.sendVerificationOtp()

    Sends an OTP (one-time password) code to the user's email for sign-in. The user must then call signIn.emailOtp() with the received code.

    Parameters

    View parameters
    ParameterTypeRequired
    emailstring✓
    type"email-verification" | "sign-in" | "forget-password"✓
    const { error } = await client.auth.emailOtp.sendVerificationOtp({
      email: 'user@example.com',
      type: 'sign-in'
    })
    
    if (error) {
    console.error('Failed to send OTP:', error.message)
    }
  10. Sign in with OTP code

    auth.signIn.emailOtp()

    Signs in a user using an OTP code received via email. First call emailOtp.sendVerificationOtp() to send the code.

    Parameters

    View parameters
    ParameterTypeRequired
    emailstring✓
    otpstring✓
    const { data, error } = await client.auth.signIn.emailOtp({
      email: 'user@example.com',
      otp: '123456'
    })
    
    if (error) {
    console.error('OTP verification failed:', error.message)
    } else {
    console.log('Signed in:', data.user.email)
    }
  11. Verify email with OTP

    auth.emailOtp.verifyEmail()

    Verifies a user's email address using an OTP code sent during signup. This is typically used after signUp.email() when email verification is required.

    Parameters

    View parameters
    ParameterTypeRequired
    emailstring✓
    otpstring✓
    const { data, error } = await client.auth.emailOtp.verifyEmail({
      email: 'user@example.com',
      otp: '123456'
    })
    
    if (error) {
    console.error('Email verification failed:', error.message)
    } else {
    console.log('Email verified successfully')
    }
  12. Check verification OTP code

    auth.emailOtp.checkVerificationOtp()

    Checks if an OTP code is valid without completing the verification flow. Useful for password reset flows where you need to verify the code before allowing password change.

    Parameters

    View parameters
    ParameterTypeRequired
    emailstring✓
    type"email-verification" | "sign-in" | "forget-password"✓
    otpstring✓
    const { data, error } = await client.auth.emailOtp.checkVerificationOtp({
      email: 'user@example.com',
      otp: '123456',
      type: 'forget-password'
    })
    
    if (error || !data.success) {
    console.error('Invalid OTP code')
    }
  13. Send verification email

    auth.sendVerificationEmail()

    Sends a verification email to the user. Used for email verification after signup or email change.

    Parameters

    View parameters
    ParameterTypeRequired
    emailstring✓
    callbackURLstring | undefined
    const { error } = await client.auth.sendVerificationEmail({
      email: 'user@example.com',
      callbackURL: 'https://yourapp.com/verify-email'
    })
    
    if (error) {
    console.error('Failed to send verification email:', error.message)
    }
  14. Verify email address

    auth.verifyEmail()

    Verifies an email address using a token from a verification email link. Used for email change verification.

    Parameters

    View parameters
    ParameterTypeRequired
    queryobject✓
    const { data, error } = await client.auth.verifyEmail({
      query: {
        token: 'verification-token-from-email',
        callbackURL: 'https://yourapp.com/email-verified'
      }
    })
    
    if (error) {
    console.error('Email verification failed:', error.message)
    }
  15. Request password reset

    auth.requestPasswordReset()

    Sends a password reset email to the user. The email contains a link to reset the password.

    Parameters

    View parameters
    ParameterTypeRequired
    emailstring✓
    redirectTostring | undefined
    const { error } = await client.auth.requestPasswordReset({
      email: 'user@example.com',
      redirectTo: 'https://yourapp.com/reset-password'
    })
    
    if (error) {
    console.error('Failed to send password reset email:', error.message)
    }
  16. Fetch data from a table

    from().select()
    • Authentication token is included automatically if user is signed in
    • Returns typed data based on your database schema
    • Row-level security policies determine what data is returned
    Select all rows
    Select specific columns
    Select with filter
    Select with related tables
    const { data, error } = await client.from('todos').select('*');
  17. Insert data into a table

    from().insert()
    • Authentication token is included automatically
    • Can insert single or multiple rows
    • Returns inserted data by default
    Insert a single row
    Insert multiple rows
    const { data, error } = await client
      .from('todos')
      .insert({ title: 'Buy groceries', completed: false })
      .select();
  18. Update existing rows

    from().update()
    • Requires filter to specify which rows to update
    • Authentication token is included automatically
    const { data, error } = await client
      .from('todos')
      .update({ completed: true })
      .eq('id', 1)
      .select()
  19. Delete rows from a table

    from().delete()
    • Requires filter to specify which rows to delete
    • Authentication token is included automatically

    Parameters

    View parameters
    ParameterTypeRequired
    count"exact" | "planned" | "estimated" | undefined
    const { error } = await client
      .from('todos')
      .delete()
      .eq('id', 1)
  20. Call a stored procedure

    .rpc()
    • Authentication token is included automatically
    • Pass parameters as object
    • Returns function result
    const { data, error } = await client.rpc('get_user_stats', {
      user_id: 123,
      start_date: '2024-01-01'
    })
    
    if (error) {
    console.error('RPC error:', error.message)
    } else {
    console.log('Stats:', data)
    }
  21. Column is equal to a value

    .eq(columnvalue)

    Filters rows where the specified column equals the given value. Can be chained with other filters to create complex queries.

    const { data, error } = await client
      .from('todos')
      .select('*')
      .eq('completed', true)
  22. Column is not equal to a value

    .neq(columnvalue)

    Filters rows where the specified column does not equal the given value. Useful for excluding specific values from results.

    const { data, error } = await client
      .from('todos')
      .select('*')
      .neq('status', 'archived')
  23. Column is greater than a value

    .gt(columnvalue)

    Filters rows where the specified column is greater than the given value. Works with numeric values, dates, and other comparable types.

    const { data, error } = await client
      .from('todos')
      .select('*')
      .gt('priority', 5)
  24. Column is less than a value

    .lt(columnvalue)

    Filters rows where the specified column is less than the given value. Works with numeric values, dates, and other comparable types.

    const { data, error } = await client
      .from('todos')
      .select('*')
      .lt('priority', 10)
  25. Order results by column

    .order(columnoptions)

    Sorts query results by the specified column. Use { ascending: true } for ascending order or { ascending: false } for descending order.

    Order ascending
    Order descending
    const { data, error } = await client
      .from('todos')
      .select('*')
      .order('created_at', { ascending: true });
  26. Limit number of results

    .limit(count)

    Limits the number of rows returned by the query. Useful for pagination and preventing large result sets.

    const { data, error } = await client
      .from('todos')
      .select('*')
      .limit(10)
  27. Column is greater than or equal to a value

    .gte(columnvalue)

    Filters rows where the specified column is greater than or equal to the given value. The comparison is inclusive (includes rows where column equals the value).

    const { data, error } = await client
      .from('todos')
      .select('*')
      .gte('priority', 5)
  28. Column is less than or equal to a value

    .lte(columnvalue)

    Filters rows where the specified column is less than or equal to the given value. The comparison is inclusive (includes rows where column equals the value).

    const { data, error } = await client
      .from('todos')
      .select('*')
      .lte('priority', 10)
  29. Column matches a pattern

    .like(columnpattern)

    Filter rows where column matches pattern (case-sensitive).

    Use % as wildcard: '%pattern%' matches any string containing 'pattern'

    const { data, error } = await client
      .from('todos')
      .select('*')
      .like('title', '%groceries%')
  30. Column matches a pattern (case-insensitive)

    .ilike(columnpattern)

    Use % as wildcard: '%pattern%' matches any string containing 'pattern'

    const { data, error } = await client
      .from('todos')
      .select('*')
      .ilike('title', '%groceries%')
  31. Column is null or not null

    .is(columnvalue)

    Filters rows based on whether a column is null or not null. Use null to find rows where the column is null, or 'not.null' to find rows where it's not null.

    Is null
    Is not null
    const { data, error } = await client.from('todos').select('*').is('deleted_at', null);
  32. Column value is in an array

    .in(columnarray)

    Filters rows where the column value matches any value in the provided array. Useful for filtering by multiple possible values (e.g., status in ['pending', 'active']).

    const { data, error } = await client
      .from('todos')
      .select('*')
      .in('status', ['pending', 'in-progress'])
  33. Array or JSONB column contains value

    .contains(columnvalue)

    Filters rows where an array or JSONB column contains the specified value. For arrays, checks if the value exists in the array. For JSONB, checks if the value is contained in the JSON object.

    const { data, error } = await client
      .from('todos')
      .select('*')
      .contains('tags', ['urgent'])
  34. Column value is between two values

    .range(columnstartend)

    Range is inclusive (includes both start and end values).

    const { data, error } = await client
      .from('todos')
      .select('*')
      .range('priority', 5, 10)