A beginner-friendly dashboard showcasing all major TanStack libraries working together in a real app.
π Live Demo: https://example-react-brown.vercel.app
| Library | Version | Usage |
|---|---|---|
@tanstack/react-router |
^1.167.4 | File-based routing, type-safe navigation, SSR |
@tanstack/react-query |
^5.90.21 | Data fetching, caching, useQuery + useMutation |
@tanstack/react-table |
^8.21.3 | Headless table β sort, filter, pagination |
@tanstack/react-virtual |
^3.13.23 | Virtualized list for large datasets |
@tanstack/react-form |
^1.28.5 | Form state management with validation |
@tanstack/react-store |
^0.9.2 | Global UI state (tab, view mode, search) |
@tanstack/react-start |
^1.166.15 | Full-stack React framework (SSR) |
useQueryto fetch todos with automatic cachinguseMutationfor add / toggle / delete with optimistic updates (UI updates instantly, reverts on error)useFormwith field-level validation (required field)@tanstack/storefor global search state shared across components
useQueryfetches all 100 posts once, cached for 10 minutesuseReactTablewith sorting (click headers), global filter, and pagination- Toggle to Virtual List mode β
useVirtualizerrenders only visible rows in DOM (~5-10 rows), not all 100
- Sortable, filterable table of 10 users
- Click βοΈ to open edit dialog
useForminside dialog with per-field validationuseMutationpatches user with optimistic update
- Optimistic Updates β UI reflects changes immediately without waiting for API
- Cache Invalidation β mutations cancel in-flight queries and update cache directly
- SSR-safe hooks β
useStorewith explicit selectors,QueryClientcreated 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
- 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
@themeCSS variables - Lucide React β icons
- JSONPlaceholder β free fake REST API (todos, posts, users)
- TypeScript throughout
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)
git clone https://github.com/truongnat/example-react
cd example-react
npm install
npm run devPre-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.