Skip to content

Loa212/my-tanstack-app

Repository files navigation

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.

Requirements

  • Node ≥ 18.17
  • pnpm ≥ 8
  • Tailwind CSS v4 with the official Vite plugin (PostCSS 8+)

Tech stack & links

Quick start

pnpm install
pnpm dev       # starts Vite (default: http://localhost:5173)

Production preview:

pnpm build
pnpm preview   # serves the production build locally

Scripts

  • dev: Vite dev server
  • build: vite build + TypeScript check (tsc --noEmit)
  • preview: Preview the built app
  • test: Vitest (jsdom)
  • lint: Biome lint
  • format: Biome format
  • check: Biome check (optionally with --write in package.json if desired)

Project structure (highlights)

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

Routing

File-based routing via TanStack Router. The plugin generates src/routeTree.gen.ts.

Add a route

import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/about")({
  component: () => <div>About</div>,
});

Link between pages

import { Link } from "@tanstack/react-router";
export function Nav() {
  return <Link to="/about">About</Link>;
}

Layout

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

Data fetching

Use either:

  • Route loaders (fetch before render)
  • TanStack Query hooks (useQuery, useMutation, …)

Example: route loader

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

Example: TanStack Query

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

Styling

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

shadcn/ui

Configured via components.json. Example button in src/components/ui/button.tsx using CVA and cn.

Add components on demand:

npx shadcn@latest add button

Path aliases are set in vite.config.ts and components.json so you can import with @/….

Docs: https://ui.shadcn.com

Linting & formatting

Biome handles both:

pnpm lint
pnpm format
pnpm check

Config: biome.json

Testing

Vitest (jsdom) + Testing Library:

pnpm test

Docs: https://vitest.devhttps://testing-library.com

Build

pnpm build   # vite build + tsc --noEmit
pnpm preview

Artifacts in dist/.

Notes

  • src/routeTree.gen.ts is generated. Don’t edit it by hand. Add to files.readonlyInclude in VS Code if desired.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors