Skip to content

Why is TanStack Creating a Library for Everything - Query, Router, Table, Form, Hotkeys?

Purpose

When I saw TanStack release yet another library—Hotkeys—I wondered why Tanner Linsley keeps building new tools instead of improving existing ones. Query, Router, Table, Form, Hotkeys, Virtual, Store… when does it stop?

This post explains what makes TanStack’s philosophy different from the fragmented React ecosystem.

What I Found

I noticed a Reddit thread about TanStack Hotkeys alpha release. The top comment joked about “Tanner Linsley collecting infinity stones to snap away inferior frameworks.” But another comment asked the real question: “Are they just going to make a TanStack version of every package?”

I had the same question. We already have React Router, React Query, AG Grid, Formik. Why rebuild everything?

The Fragmented Problem

When I build React apps, I mix libraries from different authors:

  • State management: Redux, Zustand, or Jotai
  • Data fetching: SWR, React Query, or Apollo
  • Routing: React Router v6 or Next.js App Router
  • Tables: Material-UI, AG Grid, or React Table
  • Forms: Formik, React Hook Form, or Final Form

Each library has different patterns. Redux uses selectors. React Hook Form uses watch(). React Router uses useSearchParams(). The TypeScript support varies. The learning curves pile up.

I tried mixing SWR for data fetching with React Router for navigation:

Fragmented approach (before TanStack)
// SWR gives you `any` types
const { data, error } = useSWR('/api/users', fetcher)
// data is any, error is any
// React Router v6 gives loose string types
const params = useParams()
// params is Record<string, string | undefined>
// Formik requires boilerplate
<Formik
initialValues={{ email: '' }}
validationSchema={Yup.object().shape({
email: Yup.string().email().required()
})}
>
{({ values, handleChange }) => (
<input name="email" value={values.email} onChange={handleChange} />
)}
</Formik>

The patterns don’t align. I copy-paste type definitions. I write wrapper functions to bridge APIs. The cognitive overhead adds up.

What Makes TanStack Different

I looked into TanStack’s libraries and found they share core principles.

Headless by Default

TanStack Table doesn’t render tables. It gives you sorted, filtered data. You render the HTML. TanStack Form doesn’t render inputs. It manages validation state. You render the UI.

This means full control over styling and markup. No forced component trees. No design system lock-in.

Framework Agnostic

TanStack Query works in React, Vue, Svelte, and Solid. The core logic is framework-independent. Adapters handle framework-specific integration.

I can write the same Query code in React and Vue:

TanStack Query (React and Vue)
// Same API in React
const { data } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers
})
// Same API in Vue
const { data } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers
})

Type Safety First

Most React libraries added TypeScript as an afterthought. TanStack designed with TypeScript from day one.

TanStack Router infers route param types from path definitions:

TanStack Router type inference
// Define route: /users/:userId
const route = createFileRoute('/users/$userId')({
loader: ({ params }) => {
// params.userId is automatically typed as `string`
return fetchUser(params.userId)
}
})
// In component
const params = useParams()
// params.userId is `string`, not `string | undefined`

TanStack Query infers return types from query functions:

TanStack Query type inference
const { data } = useQuery({
queryKey: ['users'],
queryFn: () => fetch('/api/users').then(r => r.json())
})
// data is automatically inferred as User[]

Composability

The libraries work independently or together. Use Query for server state. Add Router for navigation. Use Table for data grids. The patterns stay consistent.

TanStack Router integrates with TanStack Query:

Router + Query integration
const route = createFileRoute('/users/$userId')({
loader: ({ params, context }) => {
// params.userId is typed from route definition
return context.queryClient.ensureQueryData({
queryKey: ['users', params.userId],
queryFn: () => fetchUser(params.userId)
})
}
})

The route param types flow into the query cache key types. End-to-end type safety from URL to database.

Why Build Everything?

I considered the alternatives. Why not use React Router? It’s mature. Why not use AG Grid? It’s feature-rich.

But I found issues:

Inconsistent Patterns

React Router, React Hook Form, and Redux have different APIs. Different mental models. Different error handling. TanStack provides one consistent approach.

Weak TypeScript Support

Many libraries use any types or require manual generics. TanStack infers types automatically. Less typing, fewer errors.

Framework Lock-in

React Router only works in React. AG Grid only works in React. If I switch to Vue or Svelte, I relearn everything. TanStack’s framework-agnostic core means my skills transfer.

Missing Features

TanStack Query popularized stale-while-revalidate caching. TanStack Router introduced type-safe routing with param inference. TanStack Table pioneered headless data grids. Innovation required building from scratch.

The TanStack Ecosystem

Here’s what TanStack offers:

LibraryPurposeKey Innovation
QueryServer stateStale-while-revalidate, background refetching
RouterType-safe routingRoute param inference, search params validation
TableHeadless data gridsVirtualization, sorting, filtering without UI
FormForm validationType-safe field access, minimal re-renders
HotkeysKeyboard shortcutsComposable combinations, conflict resolution
VirtualList virtualizationFrame-perfect scrolling, dynamic sizing
StoreClient stateSimple, type-safe, framework-agnostic

Benefits I Found

Developer Experience

One documentation site. Consistent API patterns. Single TypeScript configuration. Unified error handling.

Type Safety Across Boundaries

Router types flow into Query cache keys. Form validation types integrate with Table filters. Hotkey triggers typed with Router actions.

Performance

Libraries designed to work together. Avoid duplicate state management. Shared utilities reduce bundle size. Coordinated re-render optimization.

Future-Proofing

Framework-agnostic core survives framework shifts. Migrate from React to Vue without relearning patterns. Adopt libraries incrementally.

When I Use TanStack

I reach for TanStack when I want:

  • Full TypeScript inference without manual generics
  • Headless libraries that don’t dictate UI
  • Framework-agnostic code that survives framework shifts
  • Consistent patterns across all concerns

I don’t use TanStack when:

  • I need a quick prototype with existing tools
  • My team already knows a different stack well
  • I only need one specific feature (not the ecosystem)

Summary

In this post, I explained why TanStack builds libraries for everything. The key point is that TanStack’s libraries share a unified philosophy—headless, framework-agnostic, and fully type-safe—while the React ecosystem remains fragmented with inconsistent patterns.

TanStack isn’t reinventing wheels. It’s building a complete toolkit with consistent developer experience, end-to-end type safety, and framework flexibility.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments