@strayl/agent 0.1.9 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,294 +1,294 @@
1
- ---
2
- name: authentication
3
- description: Add authentication to a TanStack Start app using Neon Auth (managed Better Auth). Handles sign-in, sign-up, OAuth, email verification, password reset, session management, route protection, and pre-built auth UI. Use when the user needs user accounts, login, or protected routes.
4
- ---
5
-
6
- # Authentication (Neon Auth)
7
-
8
- ## When to Use
9
-
10
- - User asks to add authentication, login, sign-up, or user accounts
11
- - User wants to protect routes (dashboard, settings, profile, etc.)
12
- - User mentions "auth", "login", "register", "sign up", "sign in", "logout", "session", "password", "OAuth", "Google sign-in"
13
- - User needs user management or access control in their app
14
- - User wants OAuth (Google, GitHub) login
15
-
16
- ## When NOT to Use
17
-
18
- - User only needs a public site with no user accounts
19
- - User wants API key authentication (not session-based)
20
- - User explicitly wants to build auth from scratch without Neon Auth
21
-
22
- ## Prerequisites
23
-
24
- - A TanStack Start project (scaffolded with `web-application-creation` skill or existing)
25
- - A database created with `database-management` skill (or will be created in this workflow)
26
- - `AUTH_BASE_URL` and `VITE_AUTH_BASE_URL` env vars are automatically available after database creation (both set by `create_database`)
27
-
28
- ## Architecture
29
-
30
- Neon Auth is a **managed authentication service** built on Better Auth. It runs as a REST API deployed in the same region as the Neon database.
31
-
32
- | Concern | Solution |
33
- |---------|----------|
34
- | Auth service | Neon Auth (managed Better Auth) |
35
- | User storage | `neon_auth` schema in Neon DB (automatic) |
36
- | UI components | `@neondatabase/neon-js/auth/react/ui` (pre-built) |
37
- | Session | HTTP-only cookie (`__Secure-neonauth.session_token`), managed by SDK |
38
- | OAuth | Google works out of the box; GitHub/Vercel need custom credentials |
39
-
40
- **No custom user table needed.** Users, sessions, and accounts are stored automatically in the `neon_auth` schema.
41
-
42
- ## Workflow
43
-
44
- ### Step 1: Ensure Database Exists
45
-
46
- ```
47
- universal({ tool: "list_databases", params: {} })
48
- ```
49
-
50
- If no databases exist, create one first:
51
- ```
52
- universal({ tool: "create_database", params: { name: "main" } })
53
- ```
54
-
55
- Auth is automatically provisioned when the database is created. The `AUTH_BASE_URL`, `VITE_AUTH_BASE_URL`, and `AUTH_COOKIE_SECRET` env vars are already set in the sandbox and `.env`.
56
-
57
- ### Step 2: Install Neon Auth SDK
58
-
59
- ```bash
60
- exec({ command: "cd {app-name} && npm install @neondatabase/neon-js", background: true })
61
- ```
62
-
63
- ### Step 3: Add Auth Styles
64
-
65
- **Edit** `src/styles.css` — add the Neon UI import right after the Tailwind import:
66
-
67
- ```css
68
- @import 'tailwindcss';
69
- @import '@neondatabase/neon-js/ui/tailwind';
70
- ```
71
-
72
- If the project does NOT use Tailwind, import the pre-built CSS bundle instead. Add to the root layout or entry point:
73
- ```typescript
74
- import '@neondatabase/neon-js/ui/css';
75
- ```
76
-
77
- ### Step 4: Create Auth Client
78
-
79
- Create `src/auth.ts`. Uses `VITE_AUTH_BASE_URL` which is auto-set by `create_database` — no manual env var setup needed.
80
-
81
- ```typescript
82
- import { createAuthClient } from '@neondatabase/neon-js/auth';
83
- import { BetterAuthReactAdapter } from '@neondatabase/neon-js/auth/react';
84
-
85
- export const authClient = createAuthClient(
86
- import.meta.env.VITE_AUTH_BASE_URL,
87
- { adapter: BetterAuthReactAdapter() }
88
- );
89
- ```
90
-
91
- ### Step 5: Add Auth Provider to Root Route
92
-
93
- **Edit** `src/routes/__root.tsx` — wrap the app with `NeonAuthUIProvider`:
94
-
95
- ```typescript
96
- import { NeonAuthUIProvider } from '@neondatabase/neon-js/auth/react';
97
- import { authClient } from '../auth';
98
- ```
99
-
100
- Wrap the existing `<Outlet />` (or app content) with the provider:
101
-
102
- ```tsx
103
- <NeonAuthUIProvider authClient={authClient}>
104
- <Outlet />
105
- </NeonAuthUIProvider>
106
- ```
107
-
108
- **Optional props** for `NeonAuthUIProvider`:
109
- - `social={{ providers: ['google'] }}` — show OAuth buttons (Google works out of the box)
110
- - `emailOTP` — enable Email OTP sign-in
111
- - `credentials={{ forgotPassword: true }}` — enable forgot password flow
112
- - `navigate={navigate}` — for React Router integration
113
-
114
- **Do NOT replace** the existing root route — just add the import and wrap the content with the provider.
115
-
116
- ### Step 6: Create Auth Page Route
117
-
118
- Create `src/routes/auth.$pathname.tsx`:
119
-
120
- ```typescript
121
- import { createFileRoute } from '@tanstack/react-router';
122
- import { AuthView } from '@neondatabase/neon-js/auth/react/ui';
123
-
124
- export const Route = createFileRoute('/auth/$pathname')({
125
- component: Auth,
126
- });
127
-
128
- function Auth() {
129
- const { pathname } = Route.useParams();
130
- return (
131
- <div className="flex min-h-screen items-center justify-center">
132
- <AuthView pathname={pathname} />
133
- </div>
134
- );
135
- }
136
- ```
137
-
138
- This single route handles `/auth/sign-in`, `/auth/sign-up`, `/auth/forgot-password`, etc.
139
-
140
- ### Step 7: Create Account Page Route
141
-
142
- Create `src/routes/account.$pathname.tsx`:
143
-
144
- ```typescript
145
- import { createFileRoute } from '@tanstack/react-router';
146
- import { AccountView } from '@neondatabase/neon-js/auth/react/ui';
147
-
148
- export const Route = createFileRoute('/account/$pathname')({
149
- component: Account,
150
- });
151
-
152
- function Account() {
153
- const { pathname } = Route.useParams();
154
- return (
155
- <div className="flex min-h-screen items-center justify-center">
156
- <AccountView pathname={pathname} />
157
- </div>
158
- );
159
- }
160
- ```
161
-
162
- This handles `/account/settings`, `/account/profile`, etc.
163
-
164
- ### Step 8: Protect Routes
165
-
166
- **Edit** the main page (e.g., `src/routes/index.tsx`) to require authentication:
167
-
168
- ```typescript
169
- import { createFileRoute } from '@tanstack/react-router';
170
- import { SignedIn, UserButton, RedirectToSignIn } from '@neondatabase/neon-js/auth/react/ui';
171
- import { authClient } from '../auth';
172
-
173
- export const Route = createFileRoute('/')({
174
- component: Home,
175
- });
176
-
177
- function Home() {
178
- const { data } = authClient.useSession();
179
-
180
- return (
181
- <>
182
- <SignedIn>
183
- <div className="container mx-auto p-6">
184
- <div className="flex items-center justify-between">
185
- <h1 className="text-2xl font-bold">Welcome, {data?.user?.name}!</h1>
186
- <UserButton />
187
- </div>
188
- </div>
189
- </SignedIn>
190
- <RedirectToSignIn />
191
- </>
192
- );
193
- }
194
- ```
195
-
196
- **Key components:**
197
- - `<SignedIn>` — renders children only when authenticated
198
- - `<SignedOut>` — renders children only when NOT authenticated
199
- - `<RedirectToSignIn>` — redirects to `/auth/sign-in` if not authenticated
200
- - `<UserButton />` — user avatar/menu dropdown with sign-out
201
-
202
- ### Step 9: Restart and Preview
203
-
204
- Restart the dev server to pick up new routes and env vars, then `showPreview`. Tell the user to test `/auth/sign-in` and `/auth/sign-up`.
205
-
206
- ## File Structure (after completion)
207
-
208
- ```
209
- src/
210
- ├── auth.ts # Auth client configuration (NEW)
211
- ├── styles.css # EDITED: added neon-js/ui/tailwind import
212
- └── routes/
213
- ├── __root.tsx # EDITED: wrapped with NeonAuthUIProvider
214
- ├── auth.$pathname.tsx # NEW: handles sign-in, sign-up, forgot-password
215
- ├── account.$pathname.tsx # NEW: handles account settings, profile
216
- └── index.tsx # EDITED: added route protection
217
- ```
218
-
219
- ## Available UI Components
220
-
221
- | Component | Import | Purpose |
222
- |-----------|--------|---------|
223
- | `<AuthView>` | `@neondatabase/neon-js/auth/react/ui` | Full auth page (sign-in/sign-up/reset) |
224
- | `<AccountView>` | `@neondatabase/neon-js/auth/react/ui` | Account management page |
225
- | `<SignedIn>` | `@neondatabase/neon-js/auth/react/ui` | Render children only when authenticated |
226
- | `<SignedOut>` | `@neondatabase/neon-js/auth/react/ui` | Render children only when NOT authenticated |
227
- | `<RedirectToSignIn>` | `@neondatabase/neon-js/auth/react/ui` | Redirect to sign-in if not authenticated |
228
- | `<RedirectToSignUp>` | `@neondatabase/neon-js/auth/react/ui` | Redirect to sign-up if not authenticated |
229
- | `<UserButton>` | `@neondatabase/neon-js/auth/react/ui` | User avatar dropdown with sign-out |
230
- | `<UserAvatar>` | `@neondatabase/neon-js/auth/react/ui` | User profile picture |
231
- | `<SignInForm>` | `@neondatabase/neon-js/auth/react/ui` | Standalone sign-in form |
232
- | `<SignUpForm>` | `@neondatabase/neon-js/auth/react/ui` | Standalone sign-up form |
233
- | `<ForgotPasswordForm>` | `@neondatabase/neon-js/auth/react/ui` | Password recovery form |
234
-
235
- ## Hooks
236
-
237
- | Hook | Import | Returns |
238
- |------|--------|---------|
239
- | `authClient.useSession()` | from auth client | `{ data: { session, user }, isPending }` |
240
-
241
- ## Important Notes
242
-
243
- - **No custom user table.** Users are stored automatically in the `neon_auth` schema. Query with `SELECT * FROM neon_auth.user;`
244
- - **No password hashing.** Neon Auth handles all credential management.
245
- - **No session management.** Sessions are managed by the SDK via HTTP-only cookies.
246
- - **Google OAuth works immediately** with shared credentials for development. GitHub/Vercel require custom OAuth app setup.
247
- - **AUTH_BASE_URL is branch-specific.** Each Neon branch has its own auth environment — dev and prod are isolated.
248
- - Do NOT import both `@neondatabase/neon-js/ui/css` AND `@neondatabase/neon-js/ui/tailwind` — pick one based on whether the project uses Tailwind.
249
- - Do NOT install `bcryptjs`, `better-auth`, or other auth libraries — Neon Auth replaces them.
250
-
251
- ## SDK Methods Reference
252
-
253
- For programmatic auth (building custom UI instead of pre-built components):
254
-
255
- ```typescript
256
- import { authClient } from './auth';
257
-
258
- // Sign up
259
- await authClient.signUp.email({ email, password, name });
260
-
261
- // Sign in with email/password
262
- await authClient.signIn.email({ email, password });
263
-
264
- // Sign in with OAuth
265
- await authClient.signIn.social({ provider: 'google', callbackURL: '/' });
266
-
267
- // Sign out
268
- await authClient.signOut();
269
-
270
- // Get current session
271
- const { data } = await authClient.getSession();
272
- // data.session, data.user
273
-
274
- // React hook for session
275
- const { data } = authClient.useSession();
276
-
277
- // Update user profile
278
- await authClient.updateUser({ name: 'New Name' });
279
-
280
- // Change password
281
- await authClient.changePassword({ currentPassword, newPassword });
282
-
283
- // Email OTP verification
284
- await authClient.emailOtp.verifyEmail({ email, otp: code });
285
- ```
286
-
287
- ## Extending
288
-
289
- - **OAuth providers** — add `social={{ providers: ['google', 'github', 'vercel'] }}` to `NeonAuthUIProvider`
290
- - **Forgot password** — add `credentials={{ forgotPassword: true }}` to `NeonAuthUIProvider`, or use `<ForgotPasswordForm>` and `<ResetPasswordForm>` components
291
- - **Email verification** — enable in Neon Console (Settings > Auth). Use verification codes (works out of the box) or verification links (requires custom SMTP)
292
- - **Custom sign-up fields** — use `additionalFields` and `signUp` props on `NeonAuthUIProvider`
293
- - **Custom localization** — use `localization` prop to change labels (e.g., `{ SIGN_IN: 'Welcome Back' }`)
294
- - **Protected route layout** — create `src/routes/_authed.tsx` with `<SignedIn>` check for route groups
1
+ ---
2
+ name: authentication
3
+ description: Add authentication to a TanStack Start app using Neon Auth (managed Better Auth). Handles sign-in, sign-up, OAuth, email verification, password reset, session management, route protection, and pre-built auth UI. Use when the user needs user accounts, login, or protected routes.
4
+ ---
5
+
6
+ # Authentication (Neon Auth)
7
+
8
+ ## When to Use
9
+
10
+ - User asks to add authentication, login, sign-up, or user accounts
11
+ - User wants to protect routes (dashboard, settings, profile, etc.)
12
+ - User mentions "auth", "login", "register", "sign up", "sign in", "logout", "session", "password", "OAuth", "Google sign-in"
13
+ - User needs user management or access control in their app
14
+ - User wants OAuth (Google, GitHub) login
15
+
16
+ ## When NOT to Use
17
+
18
+ - User only needs a public site with no user accounts
19
+ - User wants API key authentication (not session-based)
20
+ - User explicitly wants to build auth from scratch without Neon Auth
21
+
22
+ ## Prerequisites
23
+
24
+ - A TanStack Start project (scaffolded with `web-application-creation` skill or existing)
25
+ - A database created with `database-management` skill (or will be created in this workflow)
26
+ - `AUTH_BASE_URL` and `VITE_AUTH_BASE_URL` env vars are automatically available after database creation (both set by `create_database`)
27
+
28
+ ## Architecture
29
+
30
+ Neon Auth is a **managed authentication service** built on Better Auth. It runs as a REST API deployed in the same region as the Neon database.
31
+
32
+ | Concern | Solution |
33
+ |---------|----------|
34
+ | Auth service | Neon Auth (managed Better Auth) |
35
+ | User storage | `neon_auth` schema in Neon DB (automatic) |
36
+ | UI components | `@neondatabase/neon-js/auth/react/ui` (pre-built) |
37
+ | Session | HTTP-only cookie (`__Secure-neonauth.session_token`), managed by SDK |
38
+ | OAuth | Google works out of the box; GitHub/Vercel need custom credentials |
39
+
40
+ **No custom user table needed.** Users, sessions, and accounts are stored automatically in the `neon_auth` schema.
41
+
42
+ ## Workflow
43
+
44
+ ### Step 1: Ensure Database Exists
45
+
46
+ ```
47
+ universal({ tool: "list_databases", params: {} })
48
+ ```
49
+
50
+ If no databases exist, create one first:
51
+ ```
52
+ universal({ tool: "create_database", params: { name: "main" } })
53
+ ```
54
+
55
+ Auth is automatically provisioned when the database is created. The `AUTH_BASE_URL`, `VITE_AUTH_BASE_URL`, and `AUTH_COOKIE_SECRET` env vars are already set in the sandbox and `.env`.
56
+
57
+ ### Step 2: Install Neon Auth SDK
58
+
59
+ ```bash
60
+ exec({ command: "cd {app-name} && npm install @neondatabase/neon-js", background: true })
61
+ ```
62
+
63
+ ### Step 3: Add Auth Styles
64
+
65
+ **Edit** `src/styles.css` — add the Neon UI import right after the Tailwind import:
66
+
67
+ ```css
68
+ @import 'tailwindcss';
69
+ @import '@neondatabase/neon-js/ui/tailwind';
70
+ ```
71
+
72
+ If the project does NOT use Tailwind, import the pre-built CSS bundle instead. Add to the root layout or entry point:
73
+ ```typescript
74
+ import '@neondatabase/neon-js/ui/css';
75
+ ```
76
+
77
+ ### Step 4: Create Auth Client
78
+
79
+ Create `src/auth.ts`. Uses `VITE_AUTH_BASE_URL` which is auto-set by `create_database` — no manual env var setup needed.
80
+
81
+ ```typescript
82
+ import { createAuthClient } from '@neondatabase/neon-js/auth';
83
+ import { BetterAuthReactAdapter } from '@neondatabase/neon-js/auth/react';
84
+
85
+ export const authClient = createAuthClient(
86
+ import.meta.env.VITE_AUTH_BASE_URL,
87
+ { adapter: BetterAuthReactAdapter() }
88
+ );
89
+ ```
90
+
91
+ ### Step 5: Add Auth Provider to Root Route
92
+
93
+ **Edit** `src/routes/__root.tsx` — wrap the app with `NeonAuthUIProvider`:
94
+
95
+ ```typescript
96
+ import { NeonAuthUIProvider } from '@neondatabase/neon-js/auth/react';
97
+ import { authClient } from '../auth';
98
+ ```
99
+
100
+ Wrap the existing `<Outlet />` (or app content) with the provider:
101
+
102
+ ```tsx
103
+ <NeonAuthUIProvider authClient={authClient}>
104
+ <Outlet />
105
+ </NeonAuthUIProvider>
106
+ ```
107
+
108
+ **Optional props** for `NeonAuthUIProvider`:
109
+ - `social={{ providers: ['google'] }}` — show OAuth buttons (Google works out of the box)
110
+ - `emailOTP` — enable Email OTP sign-in
111
+ - `credentials={{ forgotPassword: true }}` — enable forgot password flow
112
+ - `navigate={navigate}` — for React Router integration
113
+
114
+ **Do NOT replace** the existing root route — just add the import and wrap the content with the provider.
115
+
116
+ ### Step 6: Create Auth Page Route
117
+
118
+ Create `src/routes/auth.$pathname.tsx`:
119
+
120
+ ```typescript
121
+ import { createFileRoute } from '@tanstack/react-router';
122
+ import { AuthView } from '@neondatabase/neon-js/auth/react/ui';
123
+
124
+ export const Route = createFileRoute('/auth/$pathname')({
125
+ component: Auth,
126
+ });
127
+
128
+ function Auth() {
129
+ const { pathname } = Route.useParams();
130
+ return (
131
+ <div className="flex min-h-screen items-center justify-center">
132
+ <AuthView pathname={pathname} />
133
+ </div>
134
+ );
135
+ }
136
+ ```
137
+
138
+ This single route handles `/auth/sign-in`, `/auth/sign-up`, `/auth/forgot-password`, etc.
139
+
140
+ ### Step 7: Create Account Page Route
141
+
142
+ Create `src/routes/account.$pathname.tsx`:
143
+
144
+ ```typescript
145
+ import { createFileRoute } from '@tanstack/react-router';
146
+ import { AccountView } from '@neondatabase/neon-js/auth/react/ui';
147
+
148
+ export const Route = createFileRoute('/account/$pathname')({
149
+ component: Account,
150
+ });
151
+
152
+ function Account() {
153
+ const { pathname } = Route.useParams();
154
+ return (
155
+ <div className="flex min-h-screen items-center justify-center">
156
+ <AccountView pathname={pathname} />
157
+ </div>
158
+ );
159
+ }
160
+ ```
161
+
162
+ This handles `/account/settings`, `/account/profile`, etc.
163
+
164
+ ### Step 8: Protect Routes
165
+
166
+ **Edit** the main page (e.g., `src/routes/index.tsx`) to require authentication:
167
+
168
+ ```typescript
169
+ import { createFileRoute } from '@tanstack/react-router';
170
+ import { SignedIn, UserButton, RedirectToSignIn } from '@neondatabase/neon-js/auth/react/ui';
171
+ import { authClient } from '../auth';
172
+
173
+ export const Route = createFileRoute('/')({
174
+ component: Home,
175
+ });
176
+
177
+ function Home() {
178
+ const { data } = authClient.useSession();
179
+
180
+ return (
181
+ <>
182
+ <SignedIn>
183
+ <div className="container mx-auto p-6">
184
+ <div className="flex items-center justify-between">
185
+ <h1 className="text-2xl font-bold">Welcome, {data?.user?.name}!</h1>
186
+ <UserButton />
187
+ </div>
188
+ </div>
189
+ </SignedIn>
190
+ <RedirectToSignIn />
191
+ </>
192
+ );
193
+ }
194
+ ```
195
+
196
+ **Key components:**
197
+ - `<SignedIn>` — renders children only when authenticated
198
+ - `<SignedOut>` — renders children only when NOT authenticated
199
+ - `<RedirectToSignIn>` — redirects to `/auth/sign-in` if not authenticated
200
+ - `<UserButton />` — user avatar/menu dropdown with sign-out
201
+
202
+ ### Step 9: Restart and Preview
203
+
204
+ Restart the dev server to pick up new routes and env vars, then `showPreview`. Tell the user to test `/auth/sign-in` and `/auth/sign-up`.
205
+
206
+ ## File Structure (after completion)
207
+
208
+ ```
209
+ src/
210
+ ├── auth.ts # Auth client configuration (NEW)
211
+ ├── styles.css # EDITED: added neon-js/ui/tailwind import
212
+ └── routes/
213
+ ├── __root.tsx # EDITED: wrapped with NeonAuthUIProvider
214
+ ├── auth.$pathname.tsx # NEW: handles sign-in, sign-up, forgot-password
215
+ ├── account.$pathname.tsx # NEW: handles account settings, profile
216
+ └── index.tsx # EDITED: added route protection
217
+ ```
218
+
219
+ ## Available UI Components
220
+
221
+ | Component | Import | Purpose |
222
+ |-----------|--------|---------|
223
+ | `<AuthView>` | `@neondatabase/neon-js/auth/react/ui` | Full auth page (sign-in/sign-up/reset) |
224
+ | `<AccountView>` | `@neondatabase/neon-js/auth/react/ui` | Account management page |
225
+ | `<SignedIn>` | `@neondatabase/neon-js/auth/react/ui` | Render children only when authenticated |
226
+ | `<SignedOut>` | `@neondatabase/neon-js/auth/react/ui` | Render children only when NOT authenticated |
227
+ | `<RedirectToSignIn>` | `@neondatabase/neon-js/auth/react/ui` | Redirect to sign-in if not authenticated |
228
+ | `<RedirectToSignUp>` | `@neondatabase/neon-js/auth/react/ui` | Redirect to sign-up if not authenticated |
229
+ | `<UserButton>` | `@neondatabase/neon-js/auth/react/ui` | User avatar dropdown with sign-out |
230
+ | `<UserAvatar>` | `@neondatabase/neon-js/auth/react/ui` | User profile picture |
231
+ | `<SignInForm>` | `@neondatabase/neon-js/auth/react/ui` | Standalone sign-in form |
232
+ | `<SignUpForm>` | `@neondatabase/neon-js/auth/react/ui` | Standalone sign-up form |
233
+ | `<ForgotPasswordForm>` | `@neondatabase/neon-js/auth/react/ui` | Password recovery form |
234
+
235
+ ## Hooks
236
+
237
+ | Hook | Import | Returns |
238
+ |------|--------|---------|
239
+ | `authClient.useSession()` | from auth client | `{ data: { session, user }, isPending }` |
240
+
241
+ ## Important Notes
242
+
243
+ - **No custom user table.** Users are stored automatically in the `neon_auth` schema. Query with `SELECT * FROM neon_auth.user;`
244
+ - **No password hashing.** Neon Auth handles all credential management.
245
+ - **No session management.** Sessions are managed by the SDK via HTTP-only cookies.
246
+ - **Google OAuth works immediately** with shared credentials for development. GitHub/Vercel require custom OAuth app setup.
247
+ - **AUTH_BASE_URL is branch-specific.** Each Neon branch has its own auth environment — dev and prod are isolated.
248
+ - Do NOT import both `@neondatabase/neon-js/ui/css` AND `@neondatabase/neon-js/ui/tailwind` — pick one based on whether the project uses Tailwind.
249
+ - Do NOT install `bcryptjs`, `better-auth`, or other auth libraries — Neon Auth replaces them.
250
+
251
+ ## SDK Methods Reference
252
+
253
+ For programmatic auth (building custom UI instead of pre-built components):
254
+
255
+ ```typescript
256
+ import { authClient } from './auth';
257
+
258
+ // Sign up
259
+ await authClient.signUp.email({ email, password, name });
260
+
261
+ // Sign in with email/password
262
+ await authClient.signIn.email({ email, password });
263
+
264
+ // Sign in with OAuth
265
+ await authClient.signIn.social({ provider: 'google', callbackURL: '/' });
266
+
267
+ // Sign out
268
+ await authClient.signOut();
269
+
270
+ // Get current session
271
+ const { data } = await authClient.getSession();
272
+ // data.session, data.user
273
+
274
+ // React hook for session
275
+ const { data } = authClient.useSession();
276
+
277
+ // Update user profile
278
+ await authClient.updateUser({ name: 'New Name' });
279
+
280
+ // Change password
281
+ await authClient.changePassword({ currentPassword, newPassword });
282
+
283
+ // Email OTP verification
284
+ await authClient.emailOtp.verifyEmail({ email, otp: code });
285
+ ```
286
+
287
+ ## Extending
288
+
289
+ - **OAuth providers** — add `social={{ providers: ['google', 'github', 'vercel'] }}` to `NeonAuthUIProvider`
290
+ - **Forgot password** — add `credentials={{ forgotPassword: true }}` to `NeonAuthUIProvider`, or use `<ForgotPasswordForm>` and `<ResetPasswordForm>` components
291
+ - **Email verification** — enable in Neon Console (Settings > Auth). Use verification codes (works out of the box) or verification links (requires custom SMTP)
292
+ - **Custom sign-up fields** — use `additionalFields` and `signUp` props on `NeonAuthUIProvider`
293
+ - **Custom localization** — use `localization` prop to change labels (e.g., `{ SIGN_IN: 'Welcome Back' }`)
294
+ - **Protected route layout** — create `src/routes/_authed.tsx` with `<SignedIn>` check for route groups