Skip to content
Skills Library
Programming · Building & coding

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

Repository
skills ↗
Licence
MIT
Last repository change
17.10.2026

Assessment and security

95/ 100Class: good
Format25 / 25
Frontmatter with name and description, valid name, description up to 1,024 characters, name matching the folder.
Discoverability25 / 25
Description explains when to use the skill, has a reasonable length and uses third person.
Content30 / 35
At least 150 words and at most 500 lines, headings, step lists, examples or code.
Hygiene15 / 15
No placeholders such as TODO, no Windows paths, with a licence.
Riskno signals detected in the scan
Files in this package
9
Scripts
0
HTML comments
0
URLs in SKILL.md
2
Deprecation

No signals detected. Repository changed on 17.10.2026, without references to retired models or APIs.

Licence

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

  1. Rule
  2. Step 1: Pick the path
  3. Step 2: Wire the config
  4. Step 3: Use the generated primitives directly
  5. Step 4: Component composition via fragment masking
  6. Step 5: Optional: Zod runtime validation
  7. Step 6: Fix the editor traps
  8. Source
Original SKILL.md headings · 127 lines, 642 words
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…

Feedback and reports

Your message goes to Bartosz Sokoliński. An email address is needed only for a reply. See the privacy policy.