or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdconfiguration.mdindex.mdschema-conversion.mdtypes.md

schema-conversion.mddocs/

0

# Schema Conversion

1

2

The core functionality of zod-to-json-schema centers around the `zodToJsonSchema` function, which converts Zod schemas into JSON Schema format. This conversion supports all Zod schema types and provides flexible configuration options.

3

4

## Main Conversion Function

5

6

```typescript { .api }

7

function zodToJsonSchema<Target extends Targets = "jsonSchema7">(

8

schema: ZodSchema<any>,

9

options?: Partial<Options<Target>> | string

10

): (Target extends "jsonSchema7" ? JsonSchema7Type : object) & {

11

$schema?: string;

12

definitions?: {

13

[key: string]: Target extends "jsonSchema7"

14

? JsonSchema7Type

15

: Target extends "jsonSchema2019-09"

16

? JsonSchema7Type

17

: object;

18

};

19

};

20

```

21

22

**Parameters:**

23

- `schema`: The Zod schema to convert

24

- `options`: Configuration options or a string name for the schema

25

26

**Returns:** JSON Schema object with optional `$schema` and `definitions` properties

27

28

## Usage Examples

29

30

### Basic Conversion

31

32

```typescript

33

import { z } from "zod";

34

import { zodToJsonSchema } from "zod-to-json-schema";

35

36

const userSchema = z.object({

37

id: z.string().uuid(),

38

name: z.string().min(1),

39

email: z.string().email(),

40

age: z.number().int().min(0),

41

isActive: z.boolean()

42

});

43

44

const jsonSchema = zodToJsonSchema(userSchema);

45

```

46

47

### Named Schema Conversion

48

49

```typescript

50

// Using string name (shorthand)

51

const namedSchema = zodToJsonSchema(userSchema, "User");

52

53

// Using options object

54

const namedSchemaOptions = zodToJsonSchema(userSchema, {

55

name: "User",

56

target: "jsonSchema7"

57

});

58

```

59

60

### Complex Schema with References

61

62

```typescript

63

const addressSchema = z.object({

64

street: z.string(),

65

city: z.string(),

66

zipCode: z.string()

67

});

68

69

const personSchema = z.object({

70

name: z.string(),

71

address: addressSchema,

72

alternateAddresses: z.array(addressSchema).optional()

73

});

74

75

const jsonSchema = zodToJsonSchema(personSchema, {

76

name: "Person",

77

definitions: {

78

Address: addressSchema

79

}

80

});

81

```

82

83

## Supported Zod Schema Types

84

85

The conversion supports all Zod schema types through specialized parsers:

86

87

### Primitive Types

88

- `ZodString` - Converted to JSON Schema string type with validation constraints

89

- `ZodNumber` - Converted to JSON Schema number type with range validation

90

- `ZodBigInt` - Converted to JSON Schema integer type with constraints

91

- `ZodBoolean` - Converted to JSON Schema boolean type

92

- `ZodDate` - Converted based on `dateStrategy` option

93

- `ZodNull` - Converted to JSON Schema null type

94

- `ZodUndefined` - Converted to JSON Schema with no type (allows undefined)

95

96

### Collection Types

97

- `ZodArray` - Converted to JSON Schema array type with items schema

98

- `ZodTuple` - Converted to JSON Schema array with fixed items

99

- `ZodRecord` - Converted to JSON Schema object with `additionalProperties`

100

- `ZodMap` - Converted based on `mapStrategy` option

101

- `ZodSet` - Converted to unique array type

102

103

### Composite Types

104

- `ZodObject` - Converted to JSON Schema object with properties and required fields

105

- `ZodUnion` - Converted to JSON Schema with type array or `anyOf`

106

- `ZodDiscriminatedUnion` - Converted to JSON Schema `anyOf` with discriminator

107

- `ZodIntersection` - Converted to JSON Schema `allOf`

108

- `ZodLiteral` - Converted to JSON Schema const or enum

109

- `ZodEnum` - Converted to JSON Schema enum

110

- `ZodNativeEnum` - Converted to JSON Schema enum with native enum values

111

112

### Modifier Types

113

- `ZodOptional` - Removes property from required array

114

- `ZodNullable` - Adds null to type array

115

- `ZodDefault` - Adds default value to schema

116

- `ZodReadonly` - Passes through to inner type

117

- `ZodBranded` - Passes through to inner type

118

- `ZodCatch` - Passes through to inner type based on strategy

119

120

### Advanced Types

121

- `ZodEffects` - Handled based on `effectStrategy` option

122

- `ZodPipeline` - Handled based on `pipeStrategy` option

123

- `ZodPromise` - Passes through to inner type

124

- `ZodLazy` - Supports recursive schema definitions

125

- `ZodAny` - Converted to open schema

126

- `ZodUnknown` - Converted to open schema

127

- `ZodNever` - Converted to impossible schema

128

- `ZodNaN` - Converted to impossible schema

129

130

## Target Formats

131

132

The library supports multiple target JSON Schema formats:

133

134

```typescript { .api }

135

type Targets = "jsonSchema7" | "jsonSchema2019-09" | "openApi3" | "openAi";

136

```

137

138

### JSON Schema 7 (Default)

139

- Full JSON Schema Draft 7 support

140

- Adds `$schema: "http://json-schema.org/draft-07/schema#"`

141

142

### JSON Schema 2019-09

143

- JSON Schema Draft 2019-09 support

144

- Adds `$schema: "https://json-schema.org/draft/2019-09/schema#"`

145

146

### OpenAPI 3.0

147

- Legacy OpenAPI 3.0 compatibility

148

- Specific handling for OpenAPI constraints

149

150

### OpenAI

151

- OpenAI strict mode compatibility

152

- Converts optional properties to required but nullable

153

- Uses JSON Schema 2019-09 as base

154

- Warns about unsupported union types at root level

155

156

## Error Handling

157

158

The conversion process handles various edge cases:

159

160

- **Recursive schemas**: Detected and resolved using `$ref`

161

- **Circular references**: Handled with reference tracking

162

- **Unsupported types**: `ZodFunction`, `ZodVoid`, `ZodSymbol` return `undefined`

163

- **Invalid configurations**: Fallback to sensible defaults

164

165

## String Validation Patterns

166

167

The library includes built-in patterns for common string validations:

168

169

```typescript { .api }

170

const zodPatterns = {

171

cuid: /^[cC][^\s-]{8,}$/,

172

cuid2: /^[0-9a-z]+$/,

173

ulid: /^[0-9A-HJKMNP-TV-Z]{26}$/,

174

email: /^(?!\.)(?!.*\.\.)([a-zA-Z0-9_'+\-\.]*)[a-zA-Z0-9_+-]@([a-zA-Z0-9][a-zA-Z0-9\-]*\.)+[a-zA-Z]{2,}$/,

175

emoji: () => RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$", "u"),

176

uuid: /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/,

177

ipv4: /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,

178

ipv4Cidr: /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/,

179

ipv6: /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/,

180

ipv6Cidr: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,

181

base64: /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,

182

base64url: /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,

183

nanoid: /^[a-zA-Z0-9_-]{21}$/,

184

jwt: /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/

185

};

186

```

187

188

These patterns are automatically applied when Zod string schemas use built-in validation methods like `.email()`, `.uuid()`, etc.