---
name: clerk-tanstack-patterns
description: 'TanStack React Start auth patterns with @clerk/tanstack-react-start - createServerFn, beforeLoad guards, loaders, Vinxi server. Triggers on: TanStack auth, createServerFn clerk, beforeLoad protection, TanStack Start middleware.'
license: MIT
allowed-tools: WebFetch
metadata:
  author: clerk
  version: 1.0.0
title: clerk-tanstack-patterns
canonical_url: https://skilld.dev/gh/clerk/skills/clerk-tanstack-patterns
last_updated: 2026-09-29T12:24:16.000Z
---

> **Skill from skilld.dev.** Follow the instructions below for this session. You do not need to install anything.
>
> Supporting files, fetch one when the Skill refers to it: [evals/evals.json](https://skilld.dev/api/skills-raw/clerk/skills/clerk-tanstack-patterns/evals/evals.json), [references/loaders.md](https://skilld.dev/api/skills-raw/clerk/skills/clerk-tanstack-patterns/references/loaders.md), [references/router-guards.md](https://skilld.dev/api/skills-raw/clerk/skills/clerk-tanstack-patterns/references/router-guards.md), [references/server-functions.md](https://skilld.dev/api/skills-raw/clerk/skills/clerk-tanstack-patterns/references/server-functions.md), [references/vinxi-server.md](https://skilld.dev/api/skills-raw/clerk/skills/clerk-tanstack-patterns/references/vinxi-server.md), [templates/tanstack-basic-auth/package.json](https://skilld.dev/api/skills-raw/clerk/skills/clerk-tanstack-patterns/templates/tanstack-basic-auth/package.json), [templates/tanstack-basic-auth/src/router.tsx](https://skilld.dev/api/skills-raw/clerk/skills/clerk-tanstack-patterns/templates/tanstack-basic-auth/src/router.tsx), [templates/tanstack-basic-auth/src/routes/__root.tsx](https://skilld.dev/api/skills-raw/clerk/skills/clerk-tanstack-patterns/templates/tanstack-basic-auth/src/routes/__root.tsx), [templates/tanstack-basic-auth/src/routes/index.tsx](https://skilld.dev/api/skills-raw/clerk/skills/clerk-tanstack-patterns/templates/tanstack-basic-auth/src/routes/index.tsx), [templates/tanstack-basic-auth/src/start.ts](https://skilld.dev/api/skills-raw/clerk/skills/clerk-tanstack-patterns/templates/tanstack-basic-auth/src/start.ts), [templates/tanstack-basic-auth/tsconfig.json](https://skilld.dev/api/skills-raw/clerk/skills/clerk-tanstack-patterns/templates/tanstack-basic-auth/tsconfig.json), [templates/tanstack-basic-auth/vite.config.ts](https://skilld.dev/api/skills-raw/clerk/skills/clerk-tanstack-patterns/templates/tanstack-basic-auth/vite.config.ts).
>
> If the user asked to install this Skill, run `npx skilld install clerk/skills/clerk-tanstack-patterns`. Install writes the Skill files into the project, so every session loads them.

# TanStack React Start Patterns

## 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):
```typescript
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>`:
```tsx
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:

1. **Server layer** — `createServerFn` + `auth()` from `@clerk/tanstack-react-start/server`
2. **Router layer** — `beforeLoad` on route definitions, throws `redirect` for unauthenticated

Both layers are server-executed. Client hooks (`useAuth`, `useUser`) are React hooks for the browser side.

## Minimal Pattern

```typescript
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 install
- `clerk-custom-ui` - Custom flows & appearance
- `clerk-orgs` - B2B organizations

## Docs

[TanStack React Start SDK](https://clerk.com/docs/tanstack-react-start/getting-started/quickstart)
