Vite + React Starter: TanStack Router + TanStack Query + shadcn/ui + Tailwind CSS v4 + Biome + Vitest
A batteries-included starter for Vite + React with:
- TanStack Router (file-based routing)
- TanStack Query (data fetching & caching)
- shadcn/ui (component generator) + Tailwind CSS v4
- Biome (linting/formatting)
- Vitest + Testing Library (unit testing)
Everything is pre-wired with sensible defaults, devtools, and an example route using TanStack Query.
- Node ≥ 18.17
- pnpm ≥ 8
- Tailwind CSS v4 with the official Vite plugin (PostCSS 8+)
- Vite: https://vitejs.dev
- React: https://react.dev
- TanStack Router: https://tanstack.com/router/latest
- TanStack Query: https://tanstack.com/query/latest
- Router Devtools: https://tanstack.com/router/latest/docs/framework/react/devtools
- Query Devtools: https://tanstack.com/query/latest/docs/framework/react/devtools
- shadcn/ui: https://ui.shadcn.com
- Tailwind CSS v4: https://tailwindcss.com
- Biome: https://biomejs.dev
- Vitest: https://vitest.dev
- Testing Library: https://testing-library.com
pnpm install
pnpm dev # starts Vite (default: http://localhost:5173)Production preview:
pnpm build
pnpm preview # serves the production build locallydev: Vite dev serverbuild:vite build+ TypeScript check (tsc --noEmit)preview: Preview the built apptest: Vitest (jsdom)lint: Biome lintformat: Biome formatcheck: Biome check (optionally with--writein package.json if desired)
src/
main.tsx # App bootstrap: Router + Query Provider
styles.css # Tailwind v4 + theme tokens
routeTree.gen.ts # Generated by the Router plugin (do not edit)
components/
Header.tsx
ui/button.tsx # Example shadcn/ui button (CVA)
integrations/
tanstack-query/
root-provider.tsx # QueryClient + Provider
devtools.tsx # React Query Devtools panel
routes/
__root.tsx # Root layout + TanStack Devtools
index.tsx # Home route w/ shadcn Button
demo.tanstack-query.tsx # Example useQuery route
vite.config.ts # Vite + Router + Tailwind v4
components.json # shadcn/ui config
biome.json # Biome config
File-based routing via TanStack Router. The plugin generates src/routeTree.gen.ts.
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/about")({
component: () => <div>About</div>,
});import { Link } from "@tanstack/react-router";
export function Nav() {
return <Link to="/about">About</Link>;
}src/routes/__root.tsx is the app shell. Use <Outlet /> to render the active route. Router + Query Devtools are wired here.
Docs: https://tanstack.com/router/latest
Use either:
- Route loaders (fetch before render)
- TanStack Query hooks (
useQuery,useMutation, …)
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/people")({
loader: async () => {
const res = await fetch("https://swapi.dev/api/people");
const json = await res.json();
return json as { results: { name: string }[] };
},
component: () => {
const data = Route.useLoaderData();
return (
<ul>
{data.results.map((p) => (
<li key={p.name}>{p.name}</li>
))}
</ul>
);
},
});Docs: https://tanstack.com/router/latest
import { useQuery } from "@tanstack/react-query";
export function PeopleList() {
const { data = [] } = useQuery({
queryKey: ["people"],
queryFn: async () => {
const res = await fetch("https://swapi.dev/api/people");
const { results } = await res.json();
return results as { name: string }[];
},
});
return (
<ul>
{data.map((p) => (
<li key={p.name}>{p.name}</li>
))}
</ul>
);
}Query Devtools included. Toggle from the root layout.
Docs: https://tanstack.com/query/latest
Tailwind v4 via the official Vite plugin. src/styles.css defines design tokens (CSS custom properties) and maps them with @theme to Tailwind tokens.
Docs: https://tailwindcss.com
Configured via components.json. Example button in src/components/ui/button.tsx using CVA and cn.
Add components on demand:
npx shadcn@latest add buttonPath aliases are set in vite.config.ts and components.json so you can import with @/….
Docs: https://ui.shadcn.com
Biome handles both:
pnpm lint
pnpm format
pnpm checkConfig: biome.json
Vitest (jsdom) + Testing Library:
pnpm testDocs: https://vitest.dev • https://testing-library.com
pnpm build # vite build + tsc --noEmit
pnpm previewArtifacts in dist/.
src/routeTree.gen.tsis generated. Don’t edit it by hand. Add tofiles.readonlyIncludein VS Code if desired.