TanStack React Start Patterns
SkillDev tools'TanStack React Start auth patterns with @clerk/tanstack-react-start
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the TanStack React Start Patterns skill
What this skill tells your AI
The instructions your AI receives, as published by clerk/skills in skills/frameworks/clerk-tanstack-patterns/SKILL.md and read by ahel’s review.
What Do You Need?
| Task | Reference |
|---|---|
| Protect routes with beforeLoad | references/router-guards.md |
| Auth in createServerFn | references/server-functions.md |
| Pass auth to loaders | references/loaders.md |
| Configure Vinxi + clerkMiddleware | references/vinxi-server.md |
References
| Reference | Description |
|---|---|
references/router-guards.md | beforeLoad auth redirect |
references/server-functions.md | createServerFn with auth() |
references/loaders.md | Auth context in loaders |
references/vinxi-server.md | clerkMiddleware() setup |
Setup
npm install @clerk/tanstack-react-start
.env:
CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...
src/start.ts (Vinxi entry):
import { clerkMiddleware } from '@clerk/tanstack-react-start/server'
import { createStart } from '@tanstack/react-start'
export const startInstance = createStart(() => {
return {
requestMiddleware: [clerkMiddleware()],
}
})
src/routes/__root.tsx — wrap with <ClerkProvider>:
import { ClerkProvider } from '@clerk/tanstack-react-start'
function RootDocument({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<ClerkProvider>
{children}
</ClerkProvider>
</body>
</html>
)
}
Mental Model
TanStack Start runs on Vinxi. Auth flows through two layers:
- Server layer —
createServerFn+auth()from@clerk/tanstack-react-start/server - Router layer —
beforeLoadon route definitions, throwsredirectfor unauthenticated
Both layers are server-executed. Client hooks (useAuth, useUser) are React hooks for the browser side.
Minimal Pattern
import { createFileRoute, redirect } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'
import { auth } from '@clerk/tanstack-react-start/server'
const authStateFn = createServerFn().handler(async () => {
const { isAuthenticated, userId } = await auth()
if (!isAuthenticated) {
throw redirect({ to: '/sign-in' })
}
return { userId }
})
export const Route = createFileRoute('/dashboard')({
beforeLoad: async () => await authStateFn(),
})
Common Pitfalls
| Symptom | Cause | Fix |
|---|---|---|
auth() returns empty | Missing clerkMiddleware in start.ts | Add to requestMiddleware array |
redirect not thrown | Using return instead of throw | throw redirect(...) in TanStack |
Wrong import for auth | Mixing client/server imports | Server: @clerk/tanstack-react-start/server |
| Loader context missing userId | Not passing from beforeLoad | Return from beforeLoad, access via context |
ClerkProvider missing | Forgot root wrapping | Add to __root.tsx shell component |
See Also
clerk-setup- Initial Clerk installclerk-custom-ui- Custom flows & appearanceclerk-orgs- B2B organizations
Docs
Signals
- GitHub stars
- 71
- Forks
- 4
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
clerk-tanstack-patterns- Source
- github.com/clerk/skills