workos-authkit-tanstack-start
WorkOS AuthKit for TanStack Start
Decision Tree
1. Fetch README (BLOCKING)
├── Extract package name from install command
└── README is source of truth for ALL code patterns
2. Detect directory structure
├── src/ (TanStack Start v1.132+, default)
└── app/ (legacy vinxi-based projects)
3. Follow README install/setup exactly
└── Do not invent commands or patterns
Fetch SDK Documentation (BLOCKING)
STOP - Do not proceed until complete.
WebFetch: https://github.com/workos/authkit-tanstack-start/blob/main/README.md
From README, extract:
- Package name:
@workos/authkit-tanstack-react-start - Use that exact name for all imports
README overrides this skill if conflict.
Pre-Flight Checklist
- README fetched and package name extracted
-
@tanstack/startor@tanstack/react-startin package.json - Identify directory structure:
src/(modern) orapp/(legacy) - Environment variables set (see below)
Directory Structure Detection
Modern TanStack Start (v1.132+) uses src/:
src/
├── start.ts # Middleware config (CRITICAL)
├── router.tsx # Router setup
├── routes/
│ ├── __root.tsx # Root layout
│ ├── api.auth.callback.tsx # OAuth callback (flat route)
│ └── ...
Legacy (vinxi-based) uses app/:
app/
├── start.ts or router.tsx
├── routes/
│ └── api/auth/callback.tsx # OAuth callback (nested route)
Detection:
ls src/routes 2>/dev/null && echo "Modern (src/)" || echo "Legacy (app/)"
Environment Variables
| Variable | Format | Required |
|---|---|---|
WORKOS_API_KEY |
sk_... |
Yes |
WORKOS_CLIENT_ID |
client_... |
Yes |
WORKOS_REDIRECT_URI |
Full URL | Yes |
WORKOS_COOKIE_PASSWORD |
32+ chars | Yes |
Generate password if missing: openssl rand -base64 32
Default redirect URI: http://localhost:3000/api/auth/callback
Middleware Configuration (CRITICAL)
authkitMiddleware MUST be configured or auth will fail silently.
Create or update src/start.ts (or app/start.ts for legacy):
import { authkitMiddleware } from '@workos/authkit-tanstack-react-start';
export default {
requestMiddleware: [authkitMiddleware()],
};
Alternative pattern with createStart:
import { createStart } from '@tanstack/react-start';
import { authkitMiddleware } from '@workos/authkit-tanstack-react-start';
export default createStart({
requestMiddleware: [authkitMiddleware()],
});
Verification Checklist
-
authkitMiddlewareimported from@workos/authkit-tanstack-react-start - Middleware in
requestMiddlewarearray - File exports the config (default export or named
startInstance)
Verify: grep -r "authkitMiddleware" src/ app/ 2>/dev/null
Callback Route (CRITICAL)
Path must match WORKOS_REDIRECT_URI. For /api/auth/callback:
Modern (flat routes): src/routes/api.auth.callback.tsx
Legacy (nested routes): app/routes/api/auth/callback.tsx
import { createFileRoute } from '@tanstack/react-router';
import { handleCallbackRoute } from '@workos/authkit-tanstack-react-start';
export const Route = createFileRoute('/api/auth/callback')({
server: {
handlers: {
GET: handleCallbackRoute(),
},
},
});
Key points:
- Use
handleCallbackRoute()- do not write custom OAuth logic - Route path string must match the URI path exactly
- This is a server-only route (no component needed)
Protected Routes
Use getAuth() in route loaders to check authentication:
import { createFileRoute, redirect } from '@tanstack/react-router';
import { getAuth, getSignInUrl } from '@workos/authkit-tanstack-react-start';
export const Route = createFileRoute('/dashboard')({
loader: async () => {
const { user } = await getAuth();
if (!user) {
const signInUrl = await getSignInUrl();
throw redirect({ href: signInUrl });
}
return { user };
},
component: Dashboard,
});
Sign Out Route
import { createFileRoute, redirect } from '@tanstack/react-router';
import { signOut } from '@workos/authkit-tanstack-react-start';
export const Route = createFileRoute('/signout')({
loader: async () => {
await signOut();
throw redirect({ href: '/' });
},
});
Client-Side Hooks (Optional)
Only needed if you want reactive auth state in components.
1. Add AuthKitProvider to root:
// src/routes/__root.tsx
import { AuthKitProvider } from '@workos/authkit-tanstack-react-start/client';
function RootComponent() {
return (
<AuthKitProvider>
<Outlet />
</AuthKitProvider>
);
}
2. Use hooks in components:
import { useAuth } from '@workos/authkit-tanstack-react-start/client';
function Profile() {
const { user, isLoading } = useAuth();
// ...
}
Note: Server-side getAuth() is preferred for most use cases.
Error Recovery
"AuthKit middleware is not configured"
Cause: authkitMiddleware() not in start.ts
Fix: Create/update src/start.ts with middleware config
Verify: grep -r "authkitMiddleware" src/
"Module not found" for SDK
Cause: Wrong package name or not installed
Fix: pnpm add @workos/authkit-tanstack-react-start
Verify: ls node_modules/@workos/authkit-tanstack-react-start
Callback 404
Cause: Route file path doesn't match WORKOS_REDIRECT_URI Fix:
- URI
/api/auth/callback→ filesrc/routes/api.auth.callback.tsx(flat) orapp/routes/api/auth/callback.tsx(nested) - Route path string in
createFileRoute()must match exactly
getAuth returns undefined user
Cause: Middleware not configured or not running
Fix: Ensure authkitMiddleware() is in start.ts requestMiddleware array
"Cookie password too short"
Cause: WORKOS_COOKIE_PASSWORD < 32 chars
Fix: openssl rand -base64 32, update .env
Build fails with route type errors
Cause: Route tree not regenerated after adding routes
Fix: pnpm dev to regenerate routeTree.gen.ts
SDK Exports Reference
Server (main export):
authkitMiddleware()- Request middlewarehandleCallbackRoute()- OAuth callback handlergetAuth()- Get current sessionsignOut()- Sign out usergetSignInUrl()/getSignUpUrl()- Auth URLsswitchToOrganization()- Change org context
Client (/client subpath):
AuthKitProvider- Context provideruseAuth()- Auth state hookuseAccessToken()- Token management
More from workos/skills
workos
Use when the user asks for a WorkOS docs URL, term, or dashboard field (Sign-in endpoint, initiate_login_uri, Redirect URI, `WORKOS_*` env vars), or is implementing, debugging, or migrating WorkOS — AuthKit, SSO/SAML, Directory Sync, RBAC, FGA, MFA, Vault, Audit Logs, Admin Portal, Pipes (Connected Apps), Feature Flags, Radar (bot/fraud detection), webhooks, Custom Domains, or migrating from Auth0, Clerk, Cognito, Firebase, Supabase, Stytch, Descope, or Better Auth. Also triggers on @workos-inc/* imports.
594workos-widgets
Use when the user is implementing, embedding, or debugging a WorkOS Widget — specifically the User Management, User Profile, Admin Portal SSO Connection, or Admin Portal Domain Verification widgets. Handles the full stack — detecting the frontend (Next.js, React, React Router, TanStack Start, Vite, SvelteKit), generating access tokens via the backend SDK in use (Node, Python, Go, Ruby, PHP, Java, .NET), and wiring up the widget component correctly per the bundled OpenAPI spec. Also use when code imports from @workos-inc/widgets or the user pastes <UserManagement /> or <UserProfile /> JSX.
269workos-authkit-nextjs
Integrate WorkOS AuthKit with Next.js App Router (13+). Server-side rendering required.
64workos-authkit-base
Architectural reference for WorkOS AuthKit integrations. Fetch README first for implementation details.
42workos-authkit-react
Integrate WorkOS AuthKit with React single-page applications. Client-side only authentication. Use when the project is a React SPA without Next.js or React Router.
33workos-authkit-vanilla-js
Integrate WorkOS AuthKit with vanilla JavaScript applications. No framework required, browser-only. Use when project is plain HTML/JS, doesn't use React/Vue/etc, or mentions vanilla JavaScript authentication.
28