@trpc/openapi package overview
The @trpc/openapi package generates an OpenAPI 3.1 specification from your tRPC router. It is currently in alpha and versioned like 11.x.x-alpha, working with any recent tRPC v11 version. The generated spec can be used to generate a typed API client in any language, call tRPC endpoints via HTTP tools like Postman or Insomnia, and enable AI agent integrations such as MCP servers.
OpenAPI generation requirements and limitations
The OpenAPI generator does not require output type annotations — unlike other OpenAPI tools, .output() schemas are optional and return types are inferred from implementation automatically. However, if the server uses a data transformer, the OpenAPI clients must use the same transformer. Subscriptions are currently excluded from the generated spec, though SSE support is planned. Zod .describe() calls and JSDoc comments on types, routers, and procedures become description fields in the spec.
OpenAPI CLI generation options
The CLI command is: pnpm exec trpc-openapi ./src/server/router.ts. Options are: -e, --export <name> (default AppRouter) for the name of the exported router type; -o, --output <file> (default openapi.json) for the output file path; --title <text> (default tRPC API) for OpenAPI info.title; --version <ver> (default 0.0.0) for OpenAPI info.version; --server-url <url> (no default) for the base URL including any prefix, e.g. https://api.example.com/trpc.
OpenAPI programmatic generation
To generate an OpenAPI spec programmatically, import generateOpenAPIDocument from @trpc/openapi and call it with the router path and options object containing: exportName (router type name), title (OpenAPI info.title), version (OpenAPI info.version), and servers array with url property (base URL including prefix). The generator statically analyzes router TypeScript types and never executes code.
OpenAPI procedure mapping to HTTP methods
tRPC procedures map to HTTP methods in the generated OpenAPI spec as follows: Queries map to GET /procedure.path requests, Mutations map to POST /procedure.path requests, and Subscriptions are ignored (SSE support planned).
Hey API integration for TypeScript clients
Hey API (heyapi.dev) is the most tested OpenAPI client generator integration with tRPC. The @trpc/openapi/heyapi package provides a configureTRPCHeyApiClient helper that configures request serialization, response parsing, and error deserialization for generated SDK compatibility with tRPC endpoints. The helper bridges the gap between OpenAPI-generated clients and tRPC's transformer setup and query parameter encoding.
Hey API client generation without transformer
When tRPC backend has no data transformer, generate the client using: pnpm exec openapi-ts -i openapi.json -o ./generated. Then at runtime, import configureTRPCHeyApiClient from @trpc/openapi/heyapi and the generated client, then call configureTRPCHeyApiClient(client, { baseUrl: 'http://localhost:3000' }). Create an SDK instance with new Sdk({ client }). Queries are called as sdk.greeting({ query: { input: { name: 'World' } } }), mutations as sdk.user.create({ body: { name: 'Bob', age: 30 } }).
Hey API client generation with data transformer
When the tRPC backend uses a data transformer like superjson, generate the client using Hey API's programmatic API with createTRPCHeyApiTypeResolvers to ensure emitted types are correct. Import createClient from @hey-api/openapi-ts and createTRPCHeyApiTypeResolvers from @trpc/openapi/heyapi. Call createClient with input (openapi.json path), output (generated directory), and plugins array containing @hey-api/typescript with '~resolvers': createTRPCHeyApiTypeResolvers() and @hey-api/sdk with operations.strategy set to 'single'. At runtime, pass the transformer to configureTRPCHeyApiClient(client, { baseUrl: '...', transformer: superjson }). This allows native types like Date to be passed directly and received deserialized.
OpenAPI client generator integration requirements
To integrate correctly with tRPC's protocol, an OpenAPI client generator must: (1) Emit accurate types for classes like Date; (2) Support customizing Search Params and request/response body serialization; (3) If tRPC API uses a transformer, the client must serialize inputs and deserialize outputs using the same format; (4) For GET requests, encode input as ?input=<JSON>, not as individual query parameters. Reference the Hey API config source for a complete implementation.
Data transformers for OpenAPI clients
tRPC data transformers allow sending rich types like Date, Map, Set, and BigInt over the wire. When using an OpenAPI client, the same transformer must be configured on both server and client so inputs are serialized and outputs are deserialized correctly. Any transformer implementing the tRPC DataTransformer interface with serialize/deserialize methods works with configureTRPCHeyApiClient.
SuperJSON transformer configuration
SuperJSON is the most popular transformer for TypeScript-to-TypeScript setups. It handles Date, Map, Set, BigInt, RegExp, and more. Installation: pnpm add superjson. Server setup: import superjson and pass it to initTRPC.create({ transformer: superjson }). Client setup with Hey API: import configureTRPCHeyApiClient and superjson, then call configureTRPCHeyApiClient(client, { baseUrl: 'http://localhost:3000', transformer: superjson }).
MongoDB Extended JSON transformer configuration
MongoDB Extended JSON (EJSON) v2 is a cross-language transformer option supporting C, C#, C++, Go, Java, Node.js, Perl, PHP, Python, Ruby, and Scala. Installation: pnpm add bson. Implementation: import EJSON from bson and create a TRPCDataTransformer with serialize: (value) => EJSON.serialize(value) and deserialize: (value) => EJSON.deserialize(value as Document). Pass this transformer to both server initTRPC.create({ transformer }) and client configureTRPCHeyApiClient(client, { transformer }).
Amazon Ion transformer
Amazon Ion is a richly-typed data format with broad language support available in C, C#, D, Go, Java, JavaScript, PHP, Python, and Rust. Installation: pnpm add ion-js. Amazon Ion does not directly support the TRPCDataTransformer interface and requires boilerplate to work with tRPC in JS/TS. See the Amazon Ion test in trpc repository for the transformer implementation and full end-to-end example.
Custom transformer implementation
A custom transformer requires an object with serialize and deserialize methods matching the TRPCDataTransformer interface. The serialize method encodes rich types, and the deserialize method decodes them back. Pass the custom transformer to both initTRPC.create({ transformer }) on the server and configureTRPCHeyApiClient(client, { transformer }) on the client.
oasdiff tool for API changelog and breaking changes
The oasdiff tool compares two versions of OpenAPI specs to generate changelogs and detect breaking changes. Use 'oasdiff changelog <old-spec> <new-spec>' to get a complete changelog including minor and breaking changes. Use 'oasdiff breaking <old-spec> <new-spec>' to get a list of breaking changes only. Installation options include Homebrew, Docker, and binaries documented in the official oasdiff repository.
OpenAPI support for tRPC routers
Multiple community projects provide OpenAPI and REST support for tRPC routers: trpc-to-openapi, oRPC (orpc.unnoq.com/docs/openapi/integrations/trpc), and tRPC Studio which provides a Swagger-like UI with input forms, Try It Out, output type visualization, and CLI extractor.
trpc-openapi integration with metadata
Metadata can be used together with the trpc-openapi package to expose REST-compatible endpoints for your application. The metadata helps configure OpenAPI-specific properties for each procedure.
tRPC OpenAPI generation
Generate OpenAPI spec and REST client from tRPC router. Refer to openapi skill for implementation.