Package Exports
- json-schema-to-zod-v3
- json-schema-to-zod-v3/package.json
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.
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.8Or using yarn:
yarn add json-schema-to-zod-v3 zod@^3.23.8Or using pnpm:
pnpm add json-schema-to-zod-v3 zod@^3.23.8Quick 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: 'john@example.com',
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 patternWhat'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); // falsecreateUniqueItemsValidator()
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]); // falsedeepEqual(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] }); // trueSupported 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 schemasanyOf (Union)
{
anyOf: [{ type: 'string' }, { type: 'number' }];
}
// Must match AT LEAST ONE schemaoneOf (Exclusive)
{
oneOf: [
{ type: 'string', minLength: 5 },
{ type: 'number', minimum: 100 },
];
}
// Must match EXACTLY ONE schemanot (Negation)
{
not: {
type: 'null';
}
}
// Must NOT match the schemaOther Features
- ✅
default- Default values - ✅
description- Schema descriptions - ✅ Complex
constandenum(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: 'john@example.com',
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 metadataConversion Process
- Primitive Phase: Handlers build base type schemas
- Collection Phase: Gather all allowed type schemas
- Combination Phase: Create union if multiple types
- 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.ZodTypeAnyEdge 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
$refreferences 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:
- Check the examples in this README
- Open an issue on GitHub
- Refer to the Zod documentation for Zod-specific questions
License
MIT
Related Projects
- Zod - TypeScript-first schema validation
- JSON Schema—JSON Schema specification
Changelog
1.0.0
- Initial release
- Full Zod v3 support
- Comprehensive JSON Schema Draft 7+ support
- Production-ready with full documentation