npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

json-schema-to-zod-v3

v1.0.4

Published

Production-ready converter from JSON Schema (Draft 7+) to Zod v3 schemas with full TypeScript support

Downloads

11,473

Readme

JSON Schema to Zod v3 Converter

A production-ready TypeScript library for converting JSON Schema (Draft 7+) to Zod v3 validation schemas with full type safety and comprehensive feature support.

npm version License: Apache 2.0 TypeScript

Features

Full Zod v3 Support - Works seamlessly with Zod 3.x
Comprehensive JSON Schema Support - All major features from Draft 7+
Type Safe - Full TypeScript support with proper type inference
Built-in Security - ReDoS protection for regex patterns (enabled by default)
Well Documented - Every function and handler has detailed JSDoc comments
Production Ready - Clean architecture, proper error handling, and edge case coverage
Zero Dependencies - Only peer dependency is Zod v3

Installation

Install the package from npm along with Zod v3:

npm install json-schema-to-zod-v3 zod@^3.23.8

Or using yarn:

yarn add json-schema-to-zod-v3 zod@^3.23.8

Or using pnpm:

pnpm add json-schema-to-zod-v3 zod@^3.23.8

Quick Start

import { convertJsonSchemaToZod } from 'json-schema-to-zod-v3';
import { z } from 'zod';

// Define a JSON Schema
const jsonSchema = {
  type: 'object',
  properties: {
    name: { type: 'string', minLength: 1 },
    age: { type: 'number', minimum: 0, maximum: 120 },
    email: { type: 'string', pattern: '^[^@]+@[^@]+.[^@]+$' },
  },
  required: ['name', 'email'],
};

// Convert to Zod schema
const zodSchema = convertJsonSchemaToZod(jsonSchema);

// Use for validation
const result = zodSchema.safeParse({
  name: 'John Doe',
  email: '[email protected]',
  age: 30,
});

console.log(result.success); // true

🔒 Security

ReDoS Protection

This library includes built-in protection against ReDoS (Regular Expression Denial of Service) attacks when processing JSON Schema pattern constraints.

Why This Matters

Malicious regex patterns can cause exponential backtracking, leading to:

  • Application hangs
  • Performance degradation
  • Denial of service

Example of a dangerous pattern:

{
  type: 'string',
  pattern: '(a+)+', // ⚠️ ReDoS vulnerability
}

Protection is Automatic

ReDoS protection is enabled by default:

import { convertJsonSchemaToZod } from 'json-schema-to-zod-v3';

const schema = {
  type: 'string',
  pattern: '(a+)+', // Dangerous pattern
};

const zodSchema = convertJsonSchemaToZod(schema);
// ✅ Pattern automatically validated and rejected
// ⚠️ Warning logged to console
// Validation will safely fail for this pattern

What's Protected

  • ✅ Nested quantifiers: (a+)+, (a*)*
  • ✅ Excessive pattern length (>1,000 chars)
  • ✅ Large quantifiers (>{100})
  • ✅ Invalid regex syntax
  • ✅ Runtime timeout protection (100 ms)

Configuration

Customize protection behavior if needed:

import { setSecurityConfig } from 'json-schema-to-zod-v3';

setSecurityConfig({
  enableProtection: true, // Enable/disable protection
  warnOnUnsafe: true, // Log warnings
  throwOnUnsafe: false, // Throw errors instead
  maxPatternLength: 1000, // Max pattern length
  maxQuantifier: 100, // Max quantifier value
  timeoutMs: 100, // Timeout for regex ops
});

Manual Validation

For more control, use security utilities directly:

import { validatePattern, createSafeRegExp } from 'json-schema-to-zod-v3';

// Validate a pattern before use
const result = validatePattern('^[a-z]+$');
if (result.safe) {
  console.log('Pattern is safe');
} else {
  console.error('Unsafe:', result.reason);
}

// Create safe regex with timeout
const regex = createSafeRegExp('^[a-z]+$');
if (regex) {
  const isValid = regex.test(input);
}

Trusted vs Untrusted Input

| Input Source | Recommendation | | ------------ | ---------------------------------- | | Your schemas | ✅ Safe with defaults | | Known APIs | ✅ Safe with defaults | | User uploads | ⚠️ Keep protection enabled | | Public APIs | ⚠️ Keep protection + rate limiting |

📖 For comprehensive security guidance, see SECURITY.md

TL;DR: ReDoS protection is enabled by default. Safe for production use. Keep enabled for untrusted input.


API Reference

convertJsonSchemaToZod(schema)

Main conversion function that transforms any JSON Schema to a Zod schema.

Parameters:

  • schema: JSONSchema - JSON Schema object or boolean

Returns: z.ZodTypeAny - Zod schema equivalent

Example:

import { convertJsonSchemaToZod } from 'json-schema-to-zod-v3';

const zodSchema = convertJsonSchemaToZod({
  type: 'string',
  minLength: 5,
  maxLength: 100,
  pattern: '^[A-Z]',
});

jsonSchemaObjectToZodRawShape(schema)

Convenience function for converting object schemas to Zod object shapes.

Parameters:

  • schema: JSONSchemaObject - JSON Schema object with properties

Returns: Record<string, z.ZodTypeAny> - Object shape for z.object()

Example:

import { jsonSchemaObjectToZodRawShape } from 'json-schema-to-zod-v3';
import { z } from 'zod';

const shape = jsonSchemaObjectToZodRawShape({
  type: 'object',
  properties: {
    username: { type: 'string' },
    age: { type: 'number' },
  },
  required: ['username'],
});

const schema = z.object(shape);

Utility Functions

isValidWithSchema(schema, value)

Validates a value against a Zod schema.

import { isValidWithSchema } from 'json-schema-to-zod-v3';
import { z } from 'zod';

const schema = z.string();
isValidWithSchema(schema, 'hello'); // true
isValidWithSchema(schema, 123); // false

createUniqueItemsValidator()

Creates a validator for unique array items with deep equality.

import { createUniqueItemsValidator } from 'json-schema-to-zod-v3';

const validator = createUniqueItemsValidator();
validator([1, 2, 3]); // true
validator([1, 2, 1]); // false

deepEqual(a, b)

Performs deep equality comparison.

import { deepEqual } from 'json-schema-to-zod-v3';

deepEqual({ a: 1, b: [2, 3] }, { a: 1, b: [2, 3] }); // true

Supported JSON Schema Features

Type Keywords

| Feature | Support | Example | | ----------------- | ------- | ---------------------------------- | | type | ✅ | { "type": "string" } | | type (multiple) | ✅ | { "type": ["string", "number"] } | | const | ✅ | { "const": "fixed-value" } | | enum | ✅ | { "enum": ["a", "b", "c"] } |

String Constraints

{
  type: 'string',
  minLength: 5, // ✅ Minimum length
  maxLength: 100, // ✅ Maximum length
  pattern: '^[A-Z]', // ✅ Regular expression
}

Number Constraints

{
  type: 'number',
  minimum: 0, // ✅ Minimum value (inclusive)
  maximum: 100, // ✅ Maximum value (inclusive)
  exclusiveMinimum: 0, // ✅ Exclusive minimum
  exclusiveMaximum: 100, // ✅ Exclusive maximum
  multipleOf: 5, // ✅ Must be multiple of
}

Array Constraints

{
  type: 'array',
  items: { type: 'string' }, // ✅ All items schema
  minItems: 1, // ✅ Minimum length
  maxItems: 10, // ✅ Maximum length
  uniqueItems: true, // ✅ All items unique
  contains: { type: 'number' }, // ✅ Must contain matching items
  prefixItems: [
    // ✅ Tuple prefix
    { type: 'string' },
    { type: 'number' },
  ],
}

Tuple Support

{
  type: 'array',
  items: [{ type: 'string' }, { type: 'number' }, { type: 'boolean' }],
}
// Converts to: z.tuple([z.string(), z.number(), z.boolean()])

Object Constraints

{
  type: 'object',
  properties: {
    // ✅ Property schemas
    name: { type: 'string' },
  },
  required: ['name'], // ✅ Required fields
  additionalProperties: false, // ✅ No extra properties
  minProperties: 1, // ✅ Minimum property count
  maxProperties: 10, // ✅ Maximum property count
}

Composition Keywords

allOf (Intersection)

{
  allOf: [
    { type: 'object', properties: { name: { type: 'string' } } },
    { type: 'object', properties: { age: { type: 'number' } } },
  ];
}
// Must match ALL schemas

anyOf (Union)

{
  anyOf: [{ type: 'string' }, { type: 'number' }];
}
// Must match AT LEAST ONE schema

oneOf (Exclusive)

{
  oneOf: [
    { type: 'string', minLength: 5 },
    { type: 'number', minimum: 100 },
  ];
}
// Must match EXACTLY ONE schema

not (Negation)

{
  not: {
    type: 'null';
  }
}
// Must NOT match the schema

Other Features

  • default - Default values
  • description - Schema descriptions
  • ✅ Complex const and enum (objects/arrays)
  • ✅ Boolean schemas (true/false)
  • ✅ Implicit type detection

Examples

User Registration Schema

import { convertJsonSchemaToZod } from 'json-schema-to-zod-v3';

const registrationSchema = {
  type: 'object',
  properties: {
    username: {
      type: 'string',
      minLength: 3,
      maxLength: 20,
      pattern: '^[a-zA-Z0-9_]+$',
    },
    email: {
      type: 'string',
      pattern: '^[^@]+@[^@]+.[^@]+$',
    },
    password: {
      type: 'string',
      minLength: 8,
    },
    age: {
      type: 'number',
      minimum: 13,
      maximum: 120,
    },
    terms: {
      type: 'boolean',
      const: true,
    },
  },
  required: ['username', 'email', 'password', 'terms'],
};

const zodSchema = convertJsonSchemaToZod(registrationSchema);

// Use it
const result = zodSchema.safeParse({
  username: 'john_doe',
  email: '[email protected]',
  password: 'secure123',
  age: 25,
  terms: true,
});

API Response Schema

import { convertJsonSchemaToZod } from 'json-schema-to-zod-v3';

const responseSchema = {
  type: 'object',
  properties: {
    status: {
      type: 'string',
      enum: ['success', 'error'],
    },
    data: {
      anyOf: [{ type: 'object' }, { type: 'array' }, { type: 'null' }],
    },
    error: {
      type: 'object',
      properties: {
        code: { type: 'string' },
        message: { type: 'string' },
      },
    },
  },
  required: ['status'],
};

const zodSchema = convertJsonSchemaToZod(responseSchema);

Product Catalog Schema

import { convertJsonSchemaToZod } from 'json-schema-to-zod-v3';

const productSchema = {
  type: 'object',
  properties: {
    id: { type: 'string' },
    name: { type: 'string', minLength: 1 },
    price: {
      type: 'number',
      minimum: 0,
      multipleOf: 0.01,
    },
    category: {
      type: 'string',
      enum: ['electronics', 'clothing', 'books'],
    },
    tags: {
      type: 'array',
      items: { type: 'string' },
      uniqueItems: true,
      minItems: 1,
    },
    metadata: {
      type: 'object',
      properties: {
        createdAt: { type: 'string' },
        updatedAt: { type: 'string' },
      },
      required: ['createdAt'],
    },
  },
  required: ['id', 'name', 'price', 'category'],
};

const zodSchema = convertJsonSchemaToZod(productSchema);

Working with OpenAPI Specs

If you have an OpenAPI specification, you can extract JSON Schemas and convert them:

import { convertJsonSchemaToZod } from 'json-schema-to-zod-v3';

// Example: Extract schema from OpenAPI
const openApiSpec = {
  components: {
    schemas: {
      User: {
        type: 'object',
        properties: {
          id: { type: 'string' },
          name: { type: 'string' },
        },
        required: ['id', 'name'],
      },
    },
  },
};

// Convert the User schema
const userZodSchema = convertJsonSchemaToZod(openApiSpec.components.schemas.User);

Architecture

The library uses a clean, modular architecture:

src/
├── index.ts                    # Public API
├── types.ts                    # TypeScript type definitions
├── utils.ts                    # Utility functions
├── converter.ts                # Main conversion orchestrator
└── handlers/
    ├── primitive/              # Primitive type handlers
    │   ├── basic.ts           # Type, const, enum
    │   ├── string.ts          # String constraints
    │   ├── number.ts          # Number constraints
    │   ├── array.ts           # Array constraints
    │   └── object.ts          # Object constraints
    └── refinement/            # Refinement handlers
        ├── composition.ts     # allOf, anyOf, oneOf, not
        ├── complex.ts         # Advanced array/object features
        └── special.ts         # Edge cases and metadata

Conversion Process

  1. Primitive Phase: Handlers build base type schemas
  2. Collection Phase: Gather all allowed type schemas
  3. Combination Phase: Create union if multiple types
  4. Refinement Phase: Apply constraints and validations

TypeScript Support

The library is fully typed with TypeScript:

import { JSONSchemaObject, convertJsonSchemaToZod } from 'json-schema-to-zod-v3';

const schema: JSONSchemaObject = {
  type: 'object',
  properties: {
    name: { type: 'string' },
  },
};

// Type-safe conversion
const zodSchema = convertJsonSchemaToZod(schema);
// Type is inferred as z.ZodTypeAny

Edge Cases Handled

  • ✅ Empty enum arrays
  • ✅ Boolean schemas (true/false)
  • __proto__ in required fields
  • ✅ Conflicting constraints
  • ✅ Unicode/emoji in string length
  • ✅ Floating-point precision in multipleOf
  • ✅ Deep equality for complex types

Limitations

  • $ref references must be resolved before conversion
  • Some very advanced JSON Schema features may not be supported
  • Maximum recursion depth applies to nested schemas

Performance

The library is optimized for production use:

  • Handlers execute in optimal order
  • Minimal object allocation
  • No unnecessary schema wrapping

Migration from Zod v4

If you're coming from a Zod v4 library, the main difference is the import:

// Old (Zod v4)
import { z } from 'zod/v4';

// New (Zod v3)
import { z } from 'zod';

All other functionality remains the same.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

If you encounter any issues or have questions:

  1. Check the examples in this README
  2. Open an issue on GitHub
  3. Refer to the Zod documentation for Zod-specific questions

License

MIT

Related Projects

Changelog

1.0.0

  • Initial release
  • Full Zod v3 support
  • Comprehensive JSON Schema Draft 7+ support
  • Production-ready with full documentation