Zod is a TypeScript-first schema validation library with static type inference.
The Zod plugin for Hey API generates schemas from your OpenAPI spec, fully compatible with validators, transformers, and all core features.
Features
Section titled “Features”- Zod v3 support
- seamless integration with
@hey-api/openapi-tsecosystem - Zod schemas for requests, responses, and reusable definitions
- minimal learning curve thanks to extending the underlying technology
Installation
Section titled “Installation”In your configuration, add zod to your plugins and you’ll be ready to generate Zod artifacts. 🎉
export default { input: 'hey-api/backend', // sign up at app.heyapi.dev output: 'src/client', plugins: [ // ...other plugins { name: 'zod', compatibilityVersion: 3, }, ],};To add data validators to your SDKs, set sdk.validator to true.
export default { input: 'hey-api/backend', // sign up at app.heyapi.dev output: 'src/client', plugins: [ // ...other plugins { name: 'zod', compatibilityVersion: 3, }, { name: '@hey-api/sdk', validator: true, }, ],};Learn more about data validators in your SDKs on the SDKs page.
Output
Section titled “Output”The Zod plugin will generate the following artifacts, depending on the input specification.
Requests
Section titled “Requests”A Zod schema is generated for every request layer of each endpoint.
const zDeletePetHeaders = z.object({ api_key: z.string().optional(),});
const zDeletePetPath = z.object({ petId: z.number(),});
const zDeletePetQuery = z.object({ additionalMetadata: z.string(),});export default { input: 'hey-api/backend', // sign up at app.heyapi.dev output: 'src/client', plugins: [ // ...other plugins { name: 'zod', compatibilityVersion: 3, requests: true, }, ],};You can customize the naming and casing pattern for requests schemas using the .name and .case options.
Responses
Section titled “Responses”A single Zod schema is generated for all endpoint’s responses. If the endpoint describes multiple responses, the generated schema is a union of all possible response shapes.
const zResponse = z.union([ z.object({ foo: z.string().optional(), }), z.object({ bar: z.number().optional(), }),]);export default { input: 'hey-api/backend', // sign up at app.heyapi.dev output: 'src/client', plugins: [ // ...other plugins { name: 'zod', compatibilityVersion: 3, responses: true, }, ],};You can customize the naming and casing pattern for responses schemas using the .name and .case options.
Definitions
Section titled “Definitions”A Zod schema is generated for every reusable definition from your input.
const zFoo = z.number().int();
const zBar = z.object({ bar: z.array(z.number().int()).optional(),});export default { input: 'hey-api/backend', // sign up at app.heyapi.dev output: 'src/client', plugins: [ // ...other plugins { name: 'zod', compatibilityVersion: 3, definitions: true, }, ],};You can customize the naming and casing pattern for definitions schemas using the .name and .case options.
ISO Datetimes
Section titled “ISO Datetimes”By default, values without a timezone or with a timezone offset are not allowed in the z.string().datetime() method.
Timezone offsets
Section titled “Timezone offsets”You can allow values with timezone offsets by setting dates.offset to true.
export const zFoo = z.string().datetime({ offset: true });export default { input: 'hey-api/backend', // sign up at app.heyapi.dev output: 'src/client', plugins: [ // ...other plugins { name: 'zod', compatibilityVersion: 3, dates: { offset: true, }, }, ],};Local times
Section titled “Local times”You can allow values without a timezone by setting dates.local to true.
export const zFoo = z.string().datetime({ local: true });export default { input: 'hey-api/backend', // sign up at app.heyapi.dev output: 'src/client', plugins: [ // ...other plugins { name: 'zod', compatibilityVersion: 3, dates: { local: true, }, }, ],};Metadata
Section titled “Metadata”It’s often useful to associate a schema with some additional metadata for documentation, code generation, AI structured outputs, form validation, and other purposes. If this is your use case, you can set metadata to true to generate additional metadata about schemas.
export const zFoo = z.string().describe('Additional metadata');export default { input: 'hey-api/backend', // sign up at app.heyapi.dev output: 'src/client', plugins: [ // ...other plugins { name: 'zod', compatibilityVersion: 3, metadata: true, }, ],};In addition to Zod schemas, you can generate schema-specific types. These can be generated for all schemas or for specific resources.
export type ResponseZodType = z.infer<typeof zResponse>;export default { input: 'hey-api/backend', // sign up at app.heyapi.dev output: 'src/client', plugins: [ // ...other plugins { name: 'zod', compatibilityVersion: 3, types: { infer: false, // by default, no `z.infer` types }, responses: { types: { infer: true, // `z.infer` types only for response schemas }, }, }, ],};You can customize the naming and casing pattern for schema-specific types using the .name and .case options.
Resolvers
Section titled “Resolvers”You can further customize this plugin’s behavior using resolvers.
You can view the complete list of options in the UserConfig interface.
Examples
You can view live examples on StackBlitz or on GitHub.