Zod Schemas to OpenAPI Documentation Generator

5.4.6 · active · verified Sat Apr 18

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

Warnings

Install

Imports

Quickstart

This example demonstrates how to define Zod schemas with OpenAPI metadata for request parameters, request bodies, and responses using `.meta()`. It then generates a complete OpenAPI 3.x document that includes definitions for creating and retrieving users.

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));

view raw JSON →