OpenAPI to Zod for tRPC
Use OpenAPI schemas with Zod validators around tRPC-style procedures when a TypeScript app needs contract-first API validation.
Quick answer: does OpenAPI belong in a tRPC stack?
tRPC is usually code-first, while OpenAPI is contract-first. They can still meet when an external API, legacy service, or partner contract already owns the schema and your TypeScript app wants Zod validators at the procedure boundary.
Contract-first workflow
Start with OpenAPI when the API contract is already published or owned outside the tRPC app. Generate Zod schemas from components, review the output, then use those schemas near procedure inputs, API clients, or adapter boundaries.
- Use OpenAPI as the source of truth when another team owns the contract.
- Use Zod as the runtime guard inside TypeScript.
- Do not duplicate schema ownership across OpenAPI, Zod, and manual types.
Generate Zod from OpenAPI components
A generated Zod schema gives the TypeScript side a real runtime parser instead of relying only on generated static types.
// Generated from an OpenAPI User component.
export const UserSchema = z.object({
id: z.string(),
email: z.string().email(),
role: z.enum(["admin", "member"]),
});
export type User = z.infer<typeof UserSchema>;Use schemas around tRPC procedures
Use generated schemas at boundaries where untrusted data enters or leaves the procedure. For internal procedures, prefer a single source of truth so the schema does not drift from the OpenAPI contract.
const UserInputSchema = z.object({
id: z.string().uuid(),
});
export const userRouter = router({
byId: publicProcedure
.input(UserInputSchema)
.query(async ({ input }) => {
const response = await fetchUser(input.id);
return UserSchema.parse(response);
}),
});Validate external API responses
The strongest fit is validating responses from REST services that are already documented with OpenAPI. The tRPC procedure can expose a typed result only after the response passes the generated Zod parser.
- Treat REST response JSON as `unknown` before parsing.
- Use generated Zod output for common object, enum, array, nullable, and required-field contracts.
- Add hand-written refinements only when they are not represented in the OpenAPI schema.
Nullable and optional fields
OpenAPI nullable and optional fields need careful review because `nullable` means a value may be `null`, while optional means the property may be omitted. Generated Zod should preserve that distinction.
const ProfileSchema = z.object({
website: z.string().url().nullable(),
timezone: z.string().optional(),
});When not to use this workflow
If the tRPC app owns every contract and no external system needs OpenAPI, a code-first Zod schema may be simpler. Use OpenAPI-to-Zod when the OpenAPI document is genuinely part of the product workflow.
- Avoid converting just to add process around a purely internal router.
- Avoid two-way syncing OpenAPI and Zod manually.
- Prefer one contract owner and generated consumers.
Production checklist
Before relying on OpenAPI-to-Zod in a tRPC-style app, add fixtures for the generated schemas and keep the conversion step visible in PR review.
- Pin the OpenAPI document version used to generate validators.
- Test valid, invalid, nullable, optional, and enum payloads.
- Document whether OpenAPI or TypeScript owns the source of truth.
- Regenerate validators when the upstream contract changes.
Use FrameworkKit to generate the starter code, then review the output before shipping it in production.
Generate with OpenAPI to ZodOpenAPI to Zod resources
OpenAPI to Zod converter
Convert OpenAPI or Swagger schema components into runtime Zod validators.
Zod API schemas
Validate request bodies and API responses with Zod before data reaches application code.
Nullable OpenAPI field errors
Fix Zod parse failures when OpenAPI nullable fields are generated as optional or non-null schemas.
OpenAPI to Zod validators
Review OpenAPI component examples before generating runtime Zod validators.
Zod to JSON Schema Converter
Use the opposite direction when TypeScript-owned Zod schemas need portable JSON Schema output.
Zod API schemas
Convert TypeScript-owned Zod contracts into OpenAPI-compatible schema objects.
openapi-zod-client alternatives
Compare the openapi-zod-client npm package with the browser-only OpenAPI to Zod converter and manual schemas.
FrameworkKit vs OpenAPI code generators
Compare FrameworkKit with openapi-zod-client, Orval, and Kubb for OpenAPI to Zod workflows.
FAQ
Can tRPC use OpenAPI schemas?
Yes, when an OpenAPI contract already exists. Use generated Zod schemas at procedure boundaries or REST adapter boundaries rather than making tRPC and OpenAPI compete as sources of truth.
Should tRPC be code-first or contract-first?
tRPC is naturally code-first. Contract-first OpenAPI is useful when external APIs, partners, or another team already own the schema.
Where should generated Zod schemas live?
Keep generated schemas close to the API client or procedure adapter that consumes the OpenAPI contract, and avoid hand-editing generated files without a clear regeneration path.
Does OpenAPI to Zod replace tRPC input schemas?
No. It can provide input or response schemas when OpenAPI owns the contract, but tRPC procedures can still use hand-written Zod schemas for app-owned inputs.
Related comparisons
Related tools
Zod to JSON Schema Converter
Use a free browser-only online converter to turn Zod 4 schemas into JSON Schema for Draft 2020-12, Draft 7, AJV, or OpenAPI-compatible output.
JSON to Zod Converter
Convert JSON to Zod schemas with strict objects, optional field inference, and inferred TypeScript types.
JSON Schema to Zod
Convert a JSON Schema document into Zod validators and inferred TypeScript types in your browser.