TanStack Form for Next.js App Router - Server Actions, server validation, useActionState, Zod integration. Use when building forms in Next.js.
View on GitHubfusengine/agents
fuse-nextjs
plugins/nextjs-expert/skills/nextjs-tanstack-form/SKILL.md
January 22, 2026
Select agents to install to:
npx add-skill https://github.com/fusengine/agents/blob/main/plugins/nextjs-expert/skills/nextjs-tanstack-form/SKILL.md -a claude-code --skill nextjs-tanstack-formInstallation paths:
.claude/skills/nextjs-tanstack-form/# TanStack Form for Next.js
Type-safe forms with Server Actions and server-side validation.
## Installation
```bash
bun add @tanstack/react-form @tanstack/react-form-nextjs zod
```
---
## Shared Form Options
```typescript
// lib/forms/user-form.ts
import { formOptions } from '@tanstack/react-form'
import { z } from 'zod'
export const userSchema = z.object({
email: z.string().email('Invalid email'),
username: z.string().min(3, 'Min 3 characters'),
age: z.number().min(18, 'Must be 18+'),
})
export const userFormOpts = formOptions({
defaultValues: {
email: '',
username: '',
age: 18,
},
})
```
---
## Server Action with Validation
```typescript
// app/actions/user.ts
'use server'
import { ServerValidateError, createServerValidate } from '@tanstack/react-form-nextjs'
import { userFormOpts, userSchema } from '@/lib/forms/user-form'
import { prisma } from '@/lib/prisma'
const serverValidate = createServerValidate({
...userFormOpts,
onServerValidate: async ({ value }) => {
// Server-only validation (DB checks)
const existing = await prisma.user.findUnique({
where: { email: value.email },
})
if (existing) {
return {
fields: { email: 'Email already registered' },
}
}
if (value.age < 18) {
return 'You must be at least 18 to sign up'
}
return undefined
},
})
export async function createUser(prev: unknown, formData: FormData) {
try {
const validatedData = await serverValidate(formData)
await prisma.user.create({
data: validatedData,
})
return { success: true }
} catch (e) {
if (e instanceof ServerValidateError) {
return e.formState
}
throw e
}
}
```
---
## Client Form Component
```typescript
// app/signup/SignupForm.tsx
'use client'
import { useActionState } from 'react'
import {
initialFormState,
mergeForm,
useForm,
useStore,
useTransform,
} from '@tanstack/react-form-nextjs'
import { z } from 'zod'
import { cr