TanStack Full Demo

March 17, 2026 ยท View on GitHub

A beginner-friendly dashboard showcasing all major TanStack libraries working together in a real app.

๐Ÿ”— Live Demo: https://example-react-brown.vercel.app

TanStack Libraries Used

LibraryVersionUsage
@tanstack/react-router^1.167.4File-based routing, type-safe navigation, SSR
@tanstack/react-query^5.90.21Data fetching, caching, useQuery + useMutation
@tanstack/react-table^8.21.3Headless table โ€” sort, filter, pagination
@tanstack/react-virtual^3.13.23Virtualized list for large datasets
@tanstack/react-form^1.28.5Form state management with validation
@tanstack/react-store^0.9.2Global UI state (tab, view mode, search)
@tanstack/react-start^1.166.15Full-stack React framework (SSR)

Pages

๐ŸŸฃ /todos โ€” Query + Form + Store

  • useQuery to fetch todos with automatic caching
  • useMutation for add / toggle / delete with optimistic updates (UI updates instantly, reverts on error)
  • useForm with field-level validation (required field)
  • @tanstack/store for global search state shared across components

๐Ÿ”ต /posts โ€” Query + Table + Virtual

  • useQuery fetches all 100 posts once, cached for 10 minutes
  • useReactTable with sorting (click headers), global filter, and pagination
  • Toggle to Virtual List mode โ€” useVirtualizer renders only visible rows in DOM (~5-10 rows), not all 100

๐ŸŸข /users โ€” Query + Table + Form

  • Sortable, filterable table of 10 users
  • Click โœ๏ธ to open edit dialog
  • useForm inside dialog with per-field validation
  • useMutation patches user with optimistic update

Key Concepts Demonstrated

  • Optimistic Updates โ€” UI reflects changes immediately without waiting for API
  • Cache Invalidation โ€” mutations cancel in-flight queries and update cache directly
  • SSR-safe hooks โ€” useStore with explicit selectors, QueryClient created per-request on server
  • Virtualization โ€” 100 rows in DOM = ~10 elements vs 100 with normal rendering
  • Headless UI โ€” TanStack Table/Form/Virtual are logic-only, you own the markup

Tech Stack

  • TanStack Start (@tanstack/react-start) โ€” SSR framework
  • Vite + Nitro โ€” bundler & server (Vercel preset)
  • shadcn/ui โ€” Radix UI + CVA components (Button, Card, Input, Badge, Dialog, Checkbox...)
  • Tailwind CSS v4 โ€” utility-first styling with @theme CSS variables
  • Lucide React โ€” icons
  • JSONPlaceholder โ€” free fake REST API (todos, posts, users)
  • TypeScript throughout

Project Structure

src/
โ”œโ”€โ”€ components/
โ”‚   โ””โ”€โ”€ ui/               # shadcn/ui components
โ”‚       โ”œโ”€โ”€ button.tsx
โ”‚       โ”œโ”€โ”€ card.tsx
โ”‚       โ”œโ”€โ”€ input.tsx
โ”‚       โ”œโ”€โ”€ badge.tsx
โ”‚       โ”œโ”€โ”€ checkbox.tsx
โ”‚       โ”œโ”€โ”€ dialog.tsx
โ”‚       โ”œโ”€โ”€ label.tsx
โ”‚       โ”œโ”€โ”€ select.tsx
โ”‚       โ””โ”€โ”€ separator.tsx
โ”œโ”€โ”€ lib/
โ”‚   โ””โ”€โ”€ utils.ts          # cn() helper (clsx + tailwind-merge)
โ”œโ”€โ”€ store/
โ”‚   โ””โ”€โ”€ index.ts          # @tanstack/store global state
โ”œโ”€โ”€ routes/
โ”‚   โ”œโ”€โ”€ __root.tsx        # Root layout (QueryClientProvider, Header, Outlet)
โ”‚   โ”œโ”€โ”€ index.tsx         # Home dashboard
โ”‚   โ”œโ”€โ”€ todos.tsx         # Query + Form + Store demo
โ”‚   โ”œโ”€โ”€ posts.tsx         # Table + Virtual demo
โ”‚   โ””โ”€โ”€ users.tsx         # Table + Form + Mutation demo
โ”œโ”€โ”€ styles/
โ”‚   โ””โ”€โ”€ app.css           # Tailwind v4 + shadcn CSS variables
โ”œโ”€โ”€ router.tsx            # createRouter config
โ””โ”€โ”€ routeTree.gen.ts      # Route tree (manually maintained)

Getting Started

git clone https://github.com/truongnat/example-react
cd example-react
npm install
npm run dev

Open http://localhost:3000

Deploy

Pre-configured for Vercel โ€” just connect the repo on vercel.com, no extra settings needed.

Uses Nitro vercel preset which outputs to .vercel/output/ format automatically.

Note: JSONPlaceholder is a read-only fake API. Mutations (add/edit/delete) return correct responses but data resets on page reload.