Full-stack TypeScript app
Generate types, validators, query hooks, mocks, and forms from one OpenAPI document — the standard SKMTC combination for a TypeScript/React app.
What you'll build
A src/generated/ tree containing:
- TypeScript types matching every schema component
- Zod validators for those same schemas
- Tanstack Query hooks (
useQuery/useMutation) for every operation - MSW handlers for development-time mocking
- shadcn/ui form components for mutating operations with object bodies
All five generators converge on shared definitions — the engine produces each schema exactly once, regardless of how many generators need it.
Stack
- Vite or Next.js (your existing app, no SKMTC-runtime needed)
- React + Tanstack Query + shadcn/ui
- MSW (for dev-only mocks)
Generators used
Types: @skmtc/gen-typescript
Produces export type Pet = {...} per schema component. The
foundation everything else references.
Validators: @skmtc/gen-zod
Produces export const pet = z.object({...}) per schema component.
Used at runtime boundaries (API responses, form submissions).
Query hooks: @skmtc/gen-tanstack-query-fetch-zod
Produces useQuery for GET/DELETE and useMutation for
POST/PUT/PATCH (when there's a request body). Hooks call fetch
directly — typical first edit when cloned is replacing fetch
with a team-specific wrapper.
Mocks: @skmtc/gen-msw
Produces per-operation http.get/http.post handlers plus a shared
toRoutesList(deps) factory. Wired into the app's MSW worker for
dev-mode mocking.
Forms: @skmtc/gen-shadcn-form
Produces a React form for every POST/PUT/PATCH operation with an object body. The form references both the Zod schema (for validation) and the mutation hook (for submit) — both already generated by the upstream generators.
Setup
skmtc init myapp src/generated
skmtc install @skmtc/gen-typescript myapp
skmtc install @skmtc/gen-zod myapp
skmtc install @skmtc/gen-tanstack-query-fetch-zod myapp
skmtc install @skmtc/gen-msw myapp
skmtc install @skmtc/gen-shadcn-form myappEdit .skmtc/myapp/.settings/client.json:
{
"source": "https://api.example.com/openapi.json",
"settings": {
"basePath": "src/generated"
}
}Generate:
skmtc generate myappStep-by-step
What ends up where in src/generated/ (each generator's
toExportPath claims its own subtree):
src/generated/
├── types/
│ ├── pet.generated.ts # type + Zod schema (both generators converge on this file)
│ ├── order.generated.ts # ditto
│ └── ...
├── services/
│ ├── useGetPetById.generated.ts # query hook
│ ├── useAddPet.generated.ts # mutation hook
│ └── ...
├── forms/
│ ├── AddPet.generated.tsx # wired React form
│ └── ...
└── mocks/
└── handlers.generated.ts # all MSW handlers + toRoutesList factoryThe hooks file imports from the types/Zod file:
// src/generated/services/useGetPetById.generated.ts
import { pet, type Pet } from '../types/pet.generated.ts'
import { useQuery } from '@tanstack/react-query'
export const useGetPetById = (args: { petId: number }) => useQuery({...})The forms reference the hook and the Zod schema:
// src/generated/forms/AddPet.generated.tsx
import { pet } from '../types/pet.generated.ts'
import { useAddPet } from '../services/useAddPet.generated.ts'
// ...Everything composes because all five generators share the
(name, exportPath) cache. See cross-generator coordination
concept.
Result
In your app:
import { useGetPetById } from '@/generated/services/useGetPetById.generated.ts'
import { AddPetForm } from '@/generated/forms/AddPet.generated.tsx'
export function PetDetailPage({ id }: { id: number }) {
const { data } = useGetPetById({ petId: id })
return (
<div>
<h1>{data?.name}</h1>
<AddPetForm />
</div>
)
}Set up MSW in development:
// src/setupMsw.ts
import { setupWorker } from 'msw/browser'
import { toRoutesList } from '@/generated/mocks/handlers.generated.ts'
const worker = setupWorker(...toRoutesList({ store: yourMockStore }))Variations
- Swap fetch transport. Clone
gen-tanstack-query-fetch-zodto use your team'sapiFetchwrapper. See how to swap a peer dependency. - Supabase backend. Use
@skmtc/gen-tanstack-query-supabase-zodinstead of the fetch variant. Addgen-shadcn-selectandgen-shadcn-tablefor the search/list UI components that pair with it. - Add a table. Install
@skmtc/gen-shadcn-tablefor list-GET operations.
Source
This recipe's stack is the most common SKMTC usage pattern. Real
projects typically clone one or two of the generators (the
fetch wrapper, the form's submit-flow) to match team conventions.
The schema-level generators (gen-typescript, gen-zod,
gen-msw) usually run unmodified.
See also
- Tutorial 02: Multiple generators — the entry-point walkthrough for this combination
- Cross-generator coordination concept
- Stock generators overview
API mocks for frontend development
Drive frontend development against MSW mocks generated from your backend's OpenAPI schema — schema-first, no backend required.
Multi-project monorepo
One repo, multiple SKMTC projects writing into separate output directories — useful when you have several APIs or multiple consumer apps with different generator combinations.