zod-from-json-schema
A library that creates Zod types from JSON Schema at runtime. This is in contrast to json-schema-to-zod, which generates JavaScript source code.
Installation
npm install zod-from-json-schema
Zod 3 vs 4
Zod 4 is available both as the package version 4, but also as part of the version 3 packages. We support both, as well as Zod 3. Here's which version of this package to use:
| Zod | zod-from-json-schema |
|---|---|
| v4 proper | latest |
| v4 via 3.x | ^0.4.2 |
| v3 | ^0.1.0 |
Note that the older package for Zod 3 supports a smaller subset of JSON schema than the latest. New features will only be added to the latest.
Usage
This package supports both ESM and CommonJS formats.
ESM (ES Modules)
import { convertJsonSchemaToZod } from 'zod-from-json-schema';
// Define a JSON Schema with advanced features
const jsonSchema = {
$schema: "https://json-schema.org/draft/2020-12/schema",
type: "object",
properties: {
name: { type: "string", minLength: 2, maxLength: 50 },
age: { type: "integer", minimum: 0, maximum: 120 },
email: { type: "string", pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$" },
tags: {
type: "array",
items: { type: "string" },
uniqueItems: true,
minItems: 1,
maxItems: 10,
contains: { enum: ["user", "admin", "guest"] }
},
coordinates: {
type: "array",
prefixItems: [
{ type: "number", minimum: -90, maximum: 90 }, // latitude
{ type: "number", minimum: -180, maximum: 180 } // longitude
],
items: false // No additional items allowed
},
score: { type: "number", multipleOf: 0.5, minimum: 0, maximum: 100 }
},
required: ["name", "email"],
additionalProperties: false,
minProperties: 2,
maxProperties: 10
};
// Convert JSON Schema to Zod schema
const zodSchema = convertJsonSchemaToZod(jsonSchema);
// Use the Zod schema to validate data
try {
const validData = zodSchema.parse({
name: "John Doe",
email: "john@example.com",
age: 30,
tags: ["user", "premium", "admin"], // Contains required "admin" role
coordinates: [37.7749, -122.4194], // San Francisco lat/lng
score: 87.5 // Multiple of 0.5
});
console.log("Valid data:", validData);
} catch (error) {
console.error("Validation error:", error);
}
CommonJS
const { convertJsonSchemaToZod } = require('zod-from-json-schema');
// Define a JSON Schema
const jsonSchema = {
$schema: "https://json-schema.org/draft/2020-12/schema",
type: "object",
properties: {
name: { type: "string", minLength: 2, maxLength: 50 },
age: { type: "integer", minimum: 0, maximum: 120 },
hobbies: {
type: "array",
items: { type: "string" },
minItems: 1,
maxItems: 5
}
},
required: ["name"],
additionalProperties: false,
minProperties: 1
};
// Convert JSON Schema to Zod schema
const zodSchema = convertJsonSchemaToZod(jsonSchema);
// Use the Zod schema to validate data
try {
const validData = zodSchema.parse({
name: "John Doe",
age: 30,
hobbies: ["reading", "coding", "gaming"]
});
console.log("Valid data:", validData);
} catch (error) {
console.error("Validation error:", error);
}
API Reference
convertJsonSchemaToZod(schema)
Converts a JSON Schema object to a complete Zod schema.
- Parameters:
schema(Object): A JSON Schema object
- Returns:
- A Zod schema that validates according to the JSON Schema
jsonSchemaObjectToZodRawShape(schema)
Extracts the object properties from a JSON Schema object into a Zod raw shape. This is useful when you want to combine the properties with other Zod object configurations.
- Parameters:
schema(Object): A JSON Schema object that should have apropertiesfield
- Returns:
- A
ZodRawShapeobject that can be used withz.object()
- A
Example:
import { jsonSchemaObjectToZodRawShape } from 'zod-from-json-schema';
import { z } from 'zod';
const jsonSchema = {
properties: {
name: { type: "string" },
age: { type: "integer" }
},
required: ["name"]
};
// Get just the property definitions
const rawShape = jsonSchemaObjectToZodRawShape(jsonSchema);
// Add custom handling
const customSchema = z.object({
...rawShape,
// Add additional fields not in the JSON Schema
createdAt: z.date().default(() => new Date())
}).refine(data => data.age > 18, {
message: "Age must be over 18 to continue"
});
Supported JSON Schema Features
This library provides comprehensive support for JSON Schema Draft 2020-12 features with 100% code coverage and extensive test validation against the official JSON Schema Test Suite.
Basic Types
string- Basic string validationnumber- Numeric values (including integers)integer- Integer-only numeric valuesboolean- Boolean true/false valuesnull- Null valuesobject- Object validation with property definitionsarray- Array validation with item constraints
String Validations
minLength- Minimum string length (Unicode grapheme-aware)maxLength- Maximum string length (Unicode grapheme-aware)pattern- Regular expression pattern matching
Unicode Support: String length validation correctly counts Unicode grapheme clusters (user-perceived characters) rather than UTF-16 code units, ensuring proper validation of emoji and international text.
Number Validations
minimum- Minimum numeric valuemaximum- Maximum numeric valueexclusiveMinimum- Exclusive minimum (greater than)exclusiveMaximum- Exclusive maximum (less than)multipleOf- Multiple validation with floating-point precision handling
Draft-4 Compatibility: The legacy boolean form of exclusiveMinimum/exclusiveMaximum (e.g. { "minimum": 5, "exclusiveMinimum": true }, as used by draft-4 and Swagger 2.0) is also accepted: true makes the sibling minimum/maximum bound exclusive, and false is a no-op.
Array Validations
items- Item schema validation (supports schemas, boolean values, and arrays)prefixItems- Tuple-style positional item validation (Draft 2020-12)minItems- Minimum array lengthmaxItems- Maximum array lengthuniqueItems- Ensures all array items are uniquecontains- Validates that array contains items matching a schemaminContains- Minimum number of items matching the contains schemamaxContains- Maximum number of items matching the contains schema
Advanced Array Features:
- Boolean
itemsschemas (items: false= empty arrays only,items: true= any items allowed) - Complex tuple validation with
prefixItemsand additional items control - Sophisticated contains validation with count constraints
Object Validations
properties- Property schema definitionsrequired- Required property validation (supports special JavaScript property names)additionalProperties- Controls whether additional properties are allowedpatternProperties- Regex-based property validation (partial; see Known Limitations)propertyNames- Validation of property names themselvesdependentSchemas- Schema dependencies based on property presenceminProperties- Minimum number of object propertiesmaxProperties- Maximum number of object propertiesdependentRequired- Required properties based on other property presence
Special Property Support: Correctly handles JavaScript reserved property names like constructor and toString — inherited members are not mistaken for property values, and own keys are validated normally. __proto__ is an exception; see Known Limitations.
Schema Composition
const- Literal value constraintsenum- Enumerated value validationanyOf- Union type validation (basic cases)allOf- Intersection validation (basic cases)oneOf- Exclusive union validation (exactly one schema must match)not- Negation validationif/then/else- Conditional schema application
References and Definitions
$ref- Internal references, including JSON pointer fragments (with~0/~1and percent-encoding escapes) and references to arbitrary schema locations (e.g.#/properties/foo)$defs/definitions- Schema definitions for reuse$id- Intra-document base URI resolution (nearest-parent bases, relative and absolute URIs, URN andfile:bases)$anchor- Location-independent identifiers, scoped to their schema resource$dynamicRef/$dynamicAnchor- Resolved statically, like$ref/$anchor(no dynamic scoping; see Known Limitations)- Recursive and mutually recursive references
- Sibling keywords next to
$refapply conjunctively (Draft 2020-12 semantics)
Remote/external references (documents other than the one being converted) are not yet supported and are ignored; see Known Limitations.
Additional Features
title- Schema titles (carried over to Zod schemas)description- Schema descriptions (carried over to Zod schemas)default- Default value annotation, but ignored if it doesn't conform to the schema; a default never satisfiesrequiredfor a missing property- Boolean schemas (
true= allow anything,false= allow nothing) - Implicit type detection from constraints
- Comprehensive error messages
Currently Unsupported Features
The following JSON Schema features are not yet implemented:
References and Definitions
- Remote/external references (referencing documents other than the one being converted)
- True dynamic scoping for
$dynamicRef/$dynamicAnchor(they are resolved statically)
Advanced Object Validation
additionalProperties- Fine-grained control over additional properties (basic support exists)unevaluatedProperties- Properties not covered by schema evaluation
Advanced Array Validation
unevaluatedItems- Items not covered by schema evaluation- Complex
prefixItemsscenarios with additional item control
Meta-Schema Features
- Custom vocabularies and meta-schema validation
- Annotation collection and processing
Known Limitations
Beyond the unsupported keywords above, supported features have some known gaps:
__proto__properties: Zod removes own__proto__keys from parsed objects to prevent prototype pollution, and this library's validation runs on Zod's parse output. As a result, a__proto__entry inpropertiescannot validate its value, andrequired: ["__proto__"]is only enforced for schemas without an explicittype.- Unresolvable references are ignored: A
$ref/$dynamicRefthat cannot be resolved within the document (remote URIs, unknown anchors, dangling pointers) does not constrain the value at all; the rest of the schema still applies. $dynamicRefis resolved statically: Dynamic scoping is not implemented;$dynamicRefbehaves like$ref(and$dynamicAnchorlike$anchor), which matches the spec whenever the dynamic anchor is bookended in the same schema resource.- Degenerate reference cycles: Reference chains that lead back to themselves without making progress on the data are dropped (treated as unresolvable) when the cycle consists purely of
$ref/$dynamicRefedges. Cycles that pass through applicators that don't consume data (e.g.notorallOf) are not detected and will recurse at validation time. - Deeply recursive data: Validating recursive schemas against deeply nested data (on the order of a few hundred nesting levels, engine-dependent) can exhaust the JavaScript call stack.
unevaluatedPropertiesis ignored: In particular, discriminated unions whoseoneOfvariants differ only byunevaluatedProperties: falsewill not reject inputs that mix properties from different variants. Declaringrequiredproperties in each variant makes the variants distinguishable instead.
Standards Compliance
- JSON Schema Draft 2020-12 - Partial support for core features of the latest JSON Schema standard
- Official Test Suite - Passes the majority of tests from the official JSON Schema Test Suite (tests for unsupported features are listed in the skip list)
License
MIT