Skip to main content
When the same structure appears in multiple places, such as billing and shipping addresses, home and work phone numbers, or primary and secondary contacts, copy-pasting the definition is fragile. Change one copy and forget the other, and you have two subtly different schemas that should be identical. $defs and $ref solve this. You define the structure once in $defs and reference it wherever it’s needed. Updates happen in one place, and every reference stays in sync.

Use case

An order output with billing_address and shipping_address that must follow exactly the same structure: the same fields, the same constraints, and the same required list.

Schema pattern

Example output

Why this works

Both billing_address and shipping_address resolve to the same $defs/address definition. If you later need to add a state field or change postal_code to zip, you change it once and both addresses update. This also improves readability. A schema with ten $ref references to a well-named definition is easier to review than ten inlined copies of the same 15-line object. Reviewers can focus on the top-level structure and drill into definitions only when needed. In Zod 4, reuse in code does not automatically become $defs reuse in generated JSON Schema. Pass reused: "ref" to toJSONSchema(...) to extract repeated schemas into $defs, and add metadata like .meta({ id: "addressSchema" }) if you want a stable definition name instead of an auto-generated one.