The TanStack suite of tools is a compelling and modern tech stack which gives developers the ability to build incredibly functional full-stack applications. The suite is powered by Vinxi, which is a JavaScript SDK that builds full-stack apps with Vite so that they can be deployed anywhere JavaScript code is capable of running. The suite provides a first-class front-end developer experience for the client while also incorporating feature-rich back-end server-side expertise, so you can expect to get the best of both worlds.
In 2025, TanStack Start is likely to be quite popular alongside Astro, Next.js and Remix for building React applications. Today, we will explore the basics of some of the most used tools from the TanStack suite and see how versatile they can be for building modern React applications in 2025.
The tools that we are going to be exploring will be:
Using TanStack Query for state management
We need to get TanStack Query up and running now that we have global state management for our application. So, let's begin by installing the dependencies so run this command in your terminal:
CODEnpm install @tanstack/react-query @tanstack/react-query-devtools
With these commands, we can now have access to a global state in our application.
Next, let's create a simple blog using the free , and it also introduces a
useQueryhook for fetching the data, handling the state and displaying the data. Tailwind CSS is used for the styling.
You should now have a design that looks like this example:
Adding TanStack Form for actions
Lastly, let's complete our application by adding a form to our About page. Like in our previous examples, the first thing that we need to do is add the packages to our application.
Use this script to install them:
CODEnpm install @tanstack/react-form zod
We installed TanStack form and Zod, which is used for form validation.
All right all we have to do now is update our
routes/about.tsxfile with this new code which has our form and our application is complete:
CODEimport * as React from 'react'
import { createFileRoute } from '@tanstack/react-router'
import { DataTable } from '../components/DataTable'
import { useForm } from '@tanstack/react-form'
import { z } from 'zod'
const formSchema = z.object({
firstName: z.string().min(2, 'First name must be at least 2 characters'),
lastName: z.string().min(2, 'Last name must be at least 2 characters'),
age: z.coerce.number().min(0, 'Age must be a positive number'),
})
type FormValues = z.infer<typeof formSchema>
export const Route = createFileRoute('/about')({
component: AboutComponent,
})
function AboutComponent() {
const [errors, setErrors] = React.useState<Record<string, string>>({})
const [formState, setFormState] = React.useState<FormValues>({
firstName: '',
lastName: '',
age: 0,
})
const form = useForm<FormValues>({
defaultValues: formState,
onSubmit: async ({ value }) => {
try {
const validatedData = formSchema.parse(value)
console.log('Form submitted:', validatedData)
setErrors({})
setFormState(validatedData)
} catch (err) {
if (err instanceof z.ZodError) {
const newErrors: Record<string, string> = {}
err.errors.forEach((error) => {
if (error.path[0]) {
newErrors[error.path[0] as string] = error.message
}
})
setErrors(newErrors)
}
}
},
})
const validateField = (field: keyof FormValues, value: string | number) => {
try {
formSchema.shape[field].parse(value)
setErrors(prev => ({ ...prev, [field]: '' }))
} catch (err) {
if (err instanceof z.ZodError) {
setErrors(prev => ({ ...prev, [field]: err.errors[0].message }))
}
}
}
return (
<div className="p-2 max-w-md mx-auto">
<h3 className="text-2xl mb-4">Users</h3>
<DataTable />
<h3 className="text-2xl mt-6 mb-4">User Registration</h3>
<form
onSubmit={(e) => {
e.preventDefault()
e.stopPropagation()
void form.handleSubmit()
}}
className="space-y-4"
>
<div>
<label htmlFor="firstName" className="block mb-2">First Name</label>
<input
id="firstName"
type="text"
value={form.state.values.firstName}
onChange={(e) => {
const value = e.target.value
form.setFieldValue('firstName', value)
validateField('firstName', value)
}}
className="w-full p-2 border rounded"
/>
{errors.firstName && (
<p className="text-red-500 text-sm mt-1">
{errors.firstName}
</p>
)}
</div>
<div>
<label htmlFor="lastName" className="block mb-2">Last Name</label>
<input
id="lastName"
type="text"
value={form.state.values.lastName}
onChange={(e) => {
const value = e.target.value
form.setFieldValue('lastName', value)
validateField('lastName', value)
}}
className="w-full p-2 border rounded"
/>
{errors.lastName && (
<p className="text-red-500 text-sm mt-1">
{errors.lastName}
</p>
)}
</div>
<div>
<label htmlFor="age" className="block mb-2">Age</label>
<input
id="age"
type="number"
value={form.state.values.age}
onChange={(e) => {
const value = Number(e.target.value)
form.setFieldValue('age', value)
validateField('age', value)
}}
className="w-full p-2 border rounded"
/>
{errors.age && (
<p className="text-red-500 text-sm mt-1">
{errors.age}
</p>
)}
</div>
<button
type="submit"
className="w-full bg-blue-500 text-white p-2 rounded hover:bg-blue-600"
>
Submit
</button>
</form>
<div className="mt-6 p-4 bg-gray-600 rounded">
<h3 className="text-xl mb-2">Current Form State</h3>
<pre className="bg-slate-200 p-2 rounded text-black">
{JSON.stringify(formState, null, 2)}
</pre>
</div>
</div>
)
}
This code adds a user registration form to our About page, which also has form validation. The form outputs the data as state on the page. See the example below. Your About page should look the same:
because we have only scratched the surface. There is so much more you can do, and the documentation covers everything.
The TanStack suite also includes TanStack Virtual, which creates scrollable elements, TanStack Ranger, which builds multi-range sliders, TanStack Store, which creates even more powerful state management, and TanStack Config, which configures and publishes JavaScript packages. With this versatility, it's easy to see how the TanStack suite of tools can provide the means for developing highly performance and feature-rich React applications in 2025.
Stay up to date with tech, programming, productivity, and AI
If you enjoyed these articles, connect and follow me across
↗ Original-Artikel auf dev.to lesenVollständiger Original-ArtikelDen kompletten Beitrag mit allen Details direkt auf dev.to lesen.
SOCIAL SHARE CARD GENERATOR