A batteries-included React starter for building data-driven apps against OpenAPI-described REST APIs.
Live demo: https://timbomckay.github.io/openapi-tanstack-starter/
| Layer | Tool |
|---|---|
| Build | Vite + @vitejs/plugin-react |
| Language | TypeScript (strict) |
| UI | React 19 |
| Components | shadcn/ui (base-vega) + Base UI |
| Styling | Tailwind CSS v4 |
| Routing | TanStack Router v1 (file-based) |
| Server state | TanStack Query v5 |
| Forms | TanStack Form v1 |
| Tables | TanStack Table v8 |
| API client | Hey API (@hey-api/openapi-ts) |
| Validation | Zod v4 |
| Testing | Vitest + Testing Library |
| Linting | oxlint |
npm install
npm run api:generate # generate API clients from OpenAPI specs
npm run dev # start dev server at http://localhost:5173npm run dev # dev server + route tree auto-generation
npm run build # type check + production build
npm run preview # preview production build locally
npm run typecheck # tsc --noEmit
npm run lint # oxlint
npm run format # oxfmt (format in place)
npm run test # vitest (watch mode)
npm run api:generate # regenerate all API clients from openapi-ts.config.tssrc/
├── api/
│ ├── petstore/ # one directory per API
│ │ ├── client.ts # configure baseUrl
│ │ └── generated/ # generated by Hey API — do not edit
│ └── example/ # placeholder for your API
├── components/
│ ├── ui/ # shadcn components — do not hand-edit
│ ├── form/fields/ # reusable TanStack Form field components
│ └── data-table/ # TanStack Table wrapper
├── hooks/ # useAppForm, form context
├── routes/ # file-based routes (TanStack Router)
│ ├── index.tsx # /
│ ├── demo.tsx # /demo — form demo
│ └── pets/
│ ├── index.tsx # /pets
│ ├── new.tsx # /pets/new
│ └── $petId/
│ ├── index.tsx # /pets/:petId
│ └── edit.tsx # /pets/:petId/edit
└── main.tsx
- Add an entry to
openapi-ts.config.tspointing at your OpenAPI spec - Copy
src/api/example/client.ts, setbaseUrl, rename the export - Run
npm run api:generate - Import the client in
src/main.tsx - Use generated query/mutation hooks in your routes
Deployment is automatic via GitHub Actions on every push to main.
In your repo settings, go to Settings → Pages → Source and select GitHub Actions.