> This page location: Backend > Neon Auth > Quickstarts > React
> Full Neon documentation index: https://neon.com/docs/llms.txt

# Use Neon Auth with React (API methods)

Build your own auth UI

**Note: Beta**

The **Neon Auth with Better Auth** is in Beta. Share your feedback on [Discord](https://discord.gg/92vNTzKDGp) or via the [Neon Console](https://console.neon.tech/app/projects?modal=feedback).

**Tip: Using an AI coding tool?**

Run [`neonctl init`](https://neon.com/docs/reference/cli-init) to configure your editor with the Neon MCP server and agent skills, including Neon Auth setup guidance:

```bash
npx neonctl@latest init
```

## Create a Neon project with Auth enabled

If you don't have a Neon project yet, create one at [console.neon.tech](https://console.neon.tech).

Go to the **Auth** page in your project dashboard and click **Enable Auth**.

You can then find your Auth **Base URL** on the Configuration tab. Copy this URL - you'll need it in the next step.

## Create a React app

Create a React app using Vite.

```bash filename="Terminal"
npm create vite@latest my-app -- --template react
```

## Install the Neon SDK

The Neon SDK provides authentication methods like `signUp()`, `getSession()`, and `signOut()` for your React app.

```bash filename="Terminal"
cd my-app
npm install @neondatabase/neon-js@latest
```

## Set up environment variables

Create a `.env` file in your project root and add your Auth Base URL:

**Note:** Replace the URL with your actual Auth Base URL from the Neon Console.

```bash filename=".env"
VITE_NEON_AUTH_URL=https://ep-xxx.neonauth.us-east-2.aws.neon.build/neondb/auth
```

## Configure the Neon client

Create a `src/auth.js` file to configure your auth client:

```javascript filename="src/auth.js"
import { createAuthClient } from '@neondatabase/neon-js/auth';

export const authClient = createAuthClient(import.meta.env.VITE_NEON_AUTH_URL);
```

## Build your authentication UI

Neon JS uses a programmatic approach for managing auth state. You'll use React hooks like `useEffect` to check the session and handle auth changes.

Replace the contents of `src/App.jsx` with the following code to implement [sign-up](https://neon.com/docs/reference/javascript-sdk#auth-signup), [sign-in](https://neon.com/docs/reference/javascript-sdk#auth-signinwithpassword), and [sign-out](https://neon.com/docs/reference/javascript-sdk#auth-signout):

```jsx filename="src/App.jsx"
import { useState, useEffect } from 'react';
import { authClient } from './auth';
import './App.css';

export default function App() {
  const [session, setSession] = useState(null);
  const [user, setUser] = useState(null);
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [isSignUp, setIsSignUp] = useState(true);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    authClient.getSession().then((result) => {
      if (result.data?.session && result.data?.user) {
        setSession(result.data.session);
        setUser(result.data.user);
      }
      setLoading(false);
    });
  }, []);

  const handleSubmit = async (e) => {
    e.preventDefault();
    const result = isSignUp
      ? await authClient.signUp.email({ name: email.split('@')[0] || 'User', email, password })
      : await authClient.signIn.email({ email, password });

    if (result.error) {
      alert(result.error.message);
      return;
    }

    const sessionResult = await authClient.getSession();
    if (sessionResult.data?.session && sessionResult.data?.user) {
      setSession(sessionResult.data.session);
      setUser(sessionResult.data.user);
    }
  };

  const handleSignOut = async () => {
    await authClient.signOut();
    setSession(null);
    setUser(null);
  };

  if (loading) return <div>Loading...</div>;

  if (session && user) {
    return (
      <div>
        <h1>Logged in as {user.email}</h1>
        <button onClick={handleSignOut}>Sign Out</button>
      </div>
    );
  }

  return (
    <form onSubmit={handleSubmit}>
      <h1>{isSignUp ? 'Sign Up' : 'Sign In'}</h1>
      <input
        type="email"
        placeholder="Email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        required
      />
      <input
        type="password"
        placeholder="Password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        required
      />
      <button type="submit">{isSignUp ? 'Sign Up' : 'Sign In'}</button>
      <p>
        {isSignUp ? (
          <>
            Already have an account?{' '}
            <a
              href="#"
              onClick={(e) => {
                e.preventDefault();
                setIsSignUp(false);
              }}
            >
              Sign in
            </a>
          </>
        ) : (
          <>
            Don't have an account?{' '}
            <a
              href="#"
              onClick={(e) => {
                e.preventDefault();
                setIsSignUp(true);
              }}
            >
              Sign up
            </a>
          </>
        )}
      </p>
    </form>
  );
}
```

## Start your app

Start the development server:

Open your browser to `http://localhost:5173` and create a test user.

```bash filename="Terminal"
npm run dev
```

## See your users in the database

As users sign up, their profiles are synced to your Neon database in the `neon_auth.user` table.

Query your users table in the SQL Editor to see your new users:

```sql filename="SQL Editor"
SELECT * FROM neon_auth.user;
```

## Next steps

- [Learn about Neon Auth concepts](https://neon.com/docs/auth/overview)
- [More example apps](https://neon.com/docs/auth/overview#example-applications) in the **neon-js** `examples/` directory
- [Explore the Neon Data API](https://neon.com/docs/data-api/get-started) to build a REST API for your data
- [View complete SDK reference](https://neon.com/docs/reference/javascript-sdk)

---

## Related docs (Quickstarts)

- [Next.js](https://neon.com/docs/auth/quick-start/nextjs-api-only)
- [TanStack Router](https://neon.com/docs/auth/quick-start/tanstack-router)
