Zod Schemas to OpenAPI Documentation Generator
zod-openapi is a TypeScript library that transforms Zod schemas into OpenAPI v3.x documentation. It leverages Zod's native `.meta()` method to embed OpenAPI-specific metadata directly into your schemas, allowing you to generate comprehensive API specifications effortlessly. The current stable version is `5.4.6`, and the package is actively maintained with frequent patch releases addressing compatibility and bug fixes, alongside regular minor updates for new features and improvements.
Common errors
-
TS2304: Cannot find name 'oas31_d_exports'.
cause Missing or incorrect TypeScript type declarations, potentially due to internal module resolution issues or version conflicts.fixUpdate `zod-openapi` to version `5.4.3` or newer to resolve this specific TypeScript error. -
Error: Zod schema cannot be represented in OpenAPI
cause The structure or a specific Zod type within your schema is not correctly handled by `zod-openapi` for OpenAPI representation. This can occur with newer or complex Zod features.fixUpdate `zod-openapi` to the latest patch version (e.g., `5.4.6` for Zod 4.3+ compatibility) to resolve known schema representation issues. -
Property 'param' does not exist on type 'ZodMeta<ZodTypeAny, any>'.
cause TypeScript is not aware of the OpenAPI-specific `.meta()` extensions provided by `zod-openapi`.fixEnsure `zod-openapi` is imported in your project (e.g., `import { createDocument } from 'zod-openapi';`) to enable type augmentation. -
TypeError: Cannot read properties of undefined (reading 'discriminator')
cause Generating OpenAPI schemas for discriminated union types with specific Zod versions (e.g., Zod 4.1.13+) could lead to runtime crashes in `zod-openapi`.fixUpdate `zod-openapi` to version `5.4.4` or newer to fix issues related to discriminated union schema generation.
Warnings
- breaking The `zodSchemas` property was removed from the `.meta().override` option for Zod schemas.
- breaking The rendering of `z.undefined()` schemas changed to `{"not": {}}`.
- gotcha Compatibility issues or crashes may occur when generating OpenAPI schemas for Zod versions `4.1.13+` or `4.3+`, particularly with discriminated unions or other complex Zod types.
- gotcha To enable full TypeScript support for OpenAPI-specific properties (like `id`, `param`, `header`) within Zod's `.meta()` method, you must import `zod-openapi` somewhere in your project.
Install
-
npm install zod-openapi -
yarn add zod-openapi -
pnpm add zod-openapi
Imports
- createDocument
const { createDocument } = require('zod-openapi');import { createDocument } from 'zod-openapi';
Quickstart
import { z } from 'zod';
import { createDocument } from 'zod-openapi'; // This import enables .meta() type extensions
const userIdParam = z.string().uuid().meta({
param: {
name: 'userId',
in: 'path',
required: true,
description: 'Unique ID of the user',
},
example: 'a1b2c3d4-e5f6-7890-1234-567890abcdef',
});
const userSchema = z.object({
id: z.string().uuid().meta({
description: 'Unique identifier for the user',
readOnly: true,
}),
name: z.string().min(1).max(100).meta({
description: 'Full name of the user',
example: 'John Doe',
}),
email: z.string().email().meta({
description: 'User\'s email address',
example: 'john.doe@example.com',
}),
}).meta({
id: 'User', // Registers this schema as a reusable OpenAPI component
description: 'Schema for a user object',
});
const newUserSchema = userSchema.omit({ id: true }).meta({
id: 'NewUser',
description: 'Schema for creating a new user',
});
const document = createDocument({
openapi: '3.0.0',
info: {
title: 'User Management API',
version: '1.0.0',
description: 'API for creating and retrieving users.',
},
paths: {
'/users': {
post: {
summary: 'Create a new user',
requestBody: {
content: {
'application/json': {
schema: newUserSchema,
},
},
},
responses: {
'201': {
description: 'User created successfully',
content: {
'application/json': {
schema: userSchema,
},
},
},
},
},
},
'/users/{userId}': {
get: {
summary: 'Get user by ID',
parameters: [userIdParam],
responses: {
'200': {
description: 'User details',
content: {
'application/json': {
schema: userSchema,
},
},
},
'404': {
description: 'User not found',
},
},
},
},
},
components: {
// Schemas with an 'id' in their meta property are automatically converted
// and can be referenced. Listing them here makes them explicit.
schemas: {
User: userSchema,
NewUser: newUserSchema
}
}
});
console.log(JSON.stringify(document, null, 2));