codegen-api
/codegen-api
Set up typesafe API code generation in 2026, preferring framework-agnostic options factories over generated hooks. Walks the decision matrix for REST (OpenAPI via hey-api) and GraphQL (graphql-codegen client preset, gql.tada), wires the minimal config for the chosen stack, and uses fragment masking for component composition. Use when starting an API integration, wiring an OpenAPI spec into a frontend, setting up GraphQL types, asked about useQuery, queryOptions, TypedDocumentNode, or fragment masking, or when seeing legacy patterns like generated useGetX hooks, per-query prop types, or @graphq
- Author
- saschb2b ↗
- Repository
- skills ↗
- Licence
- MIT
- Last repository change
- 17.10.2026
Assessment and security
- Files in this package
- 9
- Scripts
- 0
- HTML comments
- 0
- URLs in SKILL.md
- 2
No signals detected. Repository changed on 17.10.2026, without references to retired models or APIs.
MIT, open: use and modify while retaining author attribution.
What it does and when to use it
Set up typesafe API code generation in 2026, preferring framework-agnostic options factories over generated hooks. Walks the decision matrix for REST (OpenAPI via hey-api) and GraphQL (graphql-codegen client preset, gql.tada), wires the minimal config for the chosen stack, and uses fragment masking for component composition. Use when starting an API integration, wiring an OpenAPI spec into a frontend, setting up GraphQL types, asked about useQuery, queryOptions, TypedDocumentNode, or fragment masking, or when seeing legacy patterns like generated useGetX hooks, per-query prop types, or @graphq
Original author description
Set up typesafe API code generation in 2026, preferring framework-agnostic options factories over generated hooks. Walks the decision matrix for REST (OpenAPI via hey-api) and GraphQL (graphql-codegen client preset, gql.tada), wires the minimal config for the chosen stack, and uses fragment masking for component composition. Use when starting an API integration, wiring an OpenAPI spec into a frontend, setting up GraphQL types, asked about useQuery, queryOptions, TypedDocumentNode, or fragment masking, or when seeing legacy patterns like generated useGetX hooks, per-query prop types, or @graphq
How it works
- Rule
- Step 1: Pick the path
- Step 2: Wire the config
- Step 3: Use the generated primitives directly
- Step 4: Component composition via fragment masking
- Step 5: Optional: Zod runtime validation
- Step 6: Fix the editor traps
- Source
SKILL.md preview
---
name: codegen-api
description: Set up typesafe API code generation in 2026, preferring framework-agnostic options factories over generated hooks. Walks the decision matrix for REST (OpenAPI via hey-api) and GraphQL (graphql-codegen client preset, gql.tada), wires the minimal config for the chosen stack, and uses fragment masking for component composition. Use when starting an API integration, wiring an OpenAPI spec into a frontend, setting up GraphQL types, asked about useQuery, queryOptions, TypedDocumentNode, or fragment masking, or when seeing legacy patterns like generated useGetX hooks, per-query prop types, or @graphql-codegen/typescript-react-apollo. Counterweight to LLM training corpora that mostly reflect the pre-2024 hooks pattern, biasing default output toward generated hooks.
tags: [frontend, api, typescript, codegen]
date: 2026-05-12
source_post: typesafe-api-codegen-2026
---
# Typesafe API Codegen
## Rule
**Generate options, not hooks. Generate documents, not per-query types.**
Both ecosystems converged in 2024-2025. REST and GraphQL codegens stopped emitting framework-specific hooks (`useGetPet`, `useFilmsQuery`) and started emitting framework-agnostic primitives that plug into the data-fetching library's existing hooks. Do not reach for legacy codegen plugins that emit hooks or per-query prop types.
This is the most common failure mode in LLM-generated API wiring: the bulk of training corpora reflects the pre-shift hooks pattern, so the default output reaches for `@graphql-codegen/typescript-react-apollo`, `typescript-react-query`, or `openapi-typescript-codegen` hook generators.
## Step 1: Pick the path
| API source | Data fetching | Pick |
| --- | --- | --- |
| OpenAPI / REST | TanStack Query (any framework) | **`@hey-api/openapi-ts`** with `@tanstack/react-query` plugin |
| GraphQL | Apollo Client or urql | **`graphql-codegen` client preset**, default `documentMode` (AST) |
| GraphQL | TanStack Query (custom fetch) | **`graphql-codegen` client preset** with `documentMode: "string"` |
| GraphQL, small schema, no build step | any | **`gql.tada`** (zero-codegen, TS inference) |
| OpenAPI / REST, existing Orval setup | TanStack Query | Stay on Orval until `queryOptions` ships. Do not migrate without cause. |
Avoid: `@graphql-codegen/typescript-react-apollo`, `@graphql-codegen/typescript-react-query`, `openapi-typescript-codegen` hook generators. Deprecated or community-stale.
## Step 2: Wire the config
**Hey API (REST → TanStack Query):**
```ts
// openapi-ts.config.ts
import { defineConfig } from "@hey-api/openapi-ts";
export default defineConfig({
input: "./openapi.yaml",
output: "src/client",
plugins: ["@hey-api/typescript", "@hey-api/sdk", "@tanstack/react-query"],
});
```
Add to `package.json`: `"codegen:api": "openapi-ts"`.
**graphql-codegen client preset (Apollo / urql):**
```ts
// codegen.ts
import type { CodegenConfig } from "@graphql-codegen/cli";
const config: CodegenConfig = {
schema: "https://api.example.com/graphql",
documents: ["src/**/*.{ts,tsx}", "!src/gql/**/*"],
ignoreNoDocuments: true,
generates: {
"./src/gql/": {
preset: "client",
config: { enumsAsTypes: true },
presetConfig: { fragmentMasking: { unmaskFunctionName: "getFragmentData" } },
},
},
};
export default config;
```
**graphql-codegen client preset (TanStack Query):** same as above plus `config.documentMode: "string"` so the codegen emits `TypedDocumentString` for a custom `execute` wrapper.
> CRITICAL. `documentMode: "string"` paired with Apollo or urql makes all query results type as `any`. Those clients want the AST default. Only use `"string"` with TanStack Query plus a custom fetch wrapper.
**gql.tada:**
```json
// tsconfig.json
{
"compilerOptions": {
"plugins": [{
"name": "gql.tada/ts-plugin",
"schema": "./schema.graphql",
"tadaOutputLocation": "./src/graphql-env.d.ts"
}]
}
}
```
No codegen script. Types update with TypeScript.
## Step 3: Use the generated primitives directly
```tsx
// REST (hey-api)
const { data } = useQuery({
...getPetByIdOptions({ path: { petId } }),
staleTime: 5000,
});
// GraphQL (codegen, Apollo / urql)
const { data } = useQuery(AllFilmsQuery);
// GraphQL (codegen, TanStack)
const { data } = useQuery({
queryKey: ["allPeople"],
queryFn: () => execute(PeopleQuery),
});
```
Do not wrap these in custom `useFilmCard` or `useGetPet` hooks. The generated primitive is already the right level of abstraction. Hook wrappers only existed historically to carry types; fragment masking now does that better.
## Step 4: Component composition via fragment masking
If the component tree has more than one layer, do not generate per-query prop types and do not build hook wrappers per component. Use fragment masking: each component declares its own data via a fragment, parents cannot see fields they did not request. Full three-layer example, ownership table, and the gql.tada equivalent (`readFragment`) in [fragments.md](./references/fragments.md).
For a single page that fetches data and renders it directly with no child components, the inferred `useQuery` type is fine. Do not add fragments to a flat component.
## Step 5: Optional: Zod runtime validation
Both hey-api and graphql-codegen can emit Zod schemas at system boundaries:
```ts
plugins: ["@hey-api/typescript", "@hey-api/sdk", "@tanstack/react-query", "zod"]
```
Useful where the data cannot be trusted (third-party APIs, user uploads).
## Step 6: Fix the editor traps
Codegen watch mode breaks ESLint's TypeScript cache. The popular VS Code GraphQL extension does not autocomplete inside `graphql()`. Fixes in [dx-pitfalls.md](./references/dx-pitfalls.md).
## Source
Based on [Typesafe API Code Generation for React in 2026](https://saschb2b.com/blog/typesafe-api-codegen-2026). Deeper detail in [fragments.md](./references/fragments.md) and [dx-pitfalls.md](./references/dx-pitfalls.md).
Files in this package (9)
- CARD.manifest.json 1 KB
- CARD.md 2 KB
- CARD.md.sigstore 4 KB
- CARD.svg 7 KB
- SKILL.md 6 KB
- permissions.yaml 1 KB
- references/dx-pitfalls.md 2 KB
- references/fragments.md 5 KB
- references/index.md 1 KB
Versions
The database has no other skills named codegen-api.
Database snapshot: 13.11.2026 · package version c6b0f5237895 (SHA-256 digest of the entire package)
Downloads in the last 30 days: 0 · ranking
Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.
Similar skills
- 100graphql-codegen
GraphQL Code Generator for TypeScript. Generates typed operations, hooks, and document nodes from GraphQL schemas. Use for type-safe GraphQL in frontend. USE WHEN: user mentions "GraphQL Codegen", "generate GraphQL types", "GraphQL TypeScript", "typed GraphQL", "client preset",… - 100type-generation
Automatic type generation from OpenAPI and GraphQL schemas. Covers openapi-typescript, graphql-codegen, and contract sync. USE WHEN: user asks about "openapi-typescript", "graphql-codegen", "generate types from API", "type generation", "API types", "schema to TypeScript" DO NOT… - 100writing-graphql-operations
Creates GraphQL queries and mutations using gql.tada and urql. Use when writing operations, implementing repositories, updating schema, or testing GraphQL code. - 100heyapi-plugin-author
Write a `@hey-api/openapi-ts` plugin that emits custom codegen on top of hey-api's IR. Use when the user wants to add a TypeScript code generator that hooks into hey-api's spec → IR pipeline — custom validators, mock factories, RPC clients, route maps, framework adapters,… - 100api-design
Design REST/GraphQL/OpenAPI contracts before implementation — API-first approach. Use when: API, endpoint, REST, GraphQL, OpenAPI, API contract, API design, HTTP endpoint, grpc, soap. - 100go-openapi
Spec-first REST development in Go with OpenAPI: generating server interfaces and clients with oapi-codegen, request validation middleware, RFC 9457 error bodies, contract testing, and detecting breaking API changes. Use when the API has or should have an OpenAPI document, when…