When a Schema Becomes Infrastructure
Zod’s executable contract does not have to stop at the function that parses a request. The same schema can carry metadata, produce a standard description for another tool, expose a common interface to a library, and appear through more than one user-facing API. The focus here is the boundary between those uses: what can be shared safely, what must be represented by policy, and why Zod’s Core, Classic, Mini, and versioned subpaths are architectural choices rather than packaging trivia.
Metadata travels beside the value
A parsed value and information about its schema serve different purposes. An application may need a user object at runtime, while a form builder needs a field title, a documentation generator needs a description, and an API tool needs an identifier. Putting all of that information into the parsed object would mix transport data with instructions about how the data should be displayed or described.
Zod 4 keeps metadata in registries. A registry associates a particular schema instance with strongly typed metadata. The metadata is available to tools that know to ask for it, but it is not inserted into the value returned by .parse(). The global registry supports common JSON Schema-oriented fields such as id, title, description, deprecated, and examples; a custom registry can enforce its own metadata type.
There are two important ways to add it. .register(registry, metadata) associates metadata with the existing schema and returns that same schema. .meta(metadata) is an immutable convenience that creates a schema instance registered in the global registry. .describe() remains available as a compatibility-oriented shorthand for a description. The difference is more than API style because metadata is attached to schema identity. If an immutable method produces a new schema, the new instance may not automatically carry every registry entry associated with its predecessor.
That identity model is useful for reusable contracts. A field schema can be registered once and then referenced by a documentation or generation tool. A global id can give a schema a stable name when it is emitted as a definition. A registry can also describe relationships among recursive schemas, where a named reference is more useful than repeating the entire shape at each occurrence.
The separation protects the parsed value from tooling concerns, but it does not make metadata harmless. Descriptions, examples, and titles may be exported into documentation or external schemas. A description that is appropriate for an internal tool may disclose more than a public response should. Metadata is therefore another boundary surface: it travels beside the runtime contract, and its consumers need their own exposure policy.
This also explains why registry entries do not automatically follow every derived schema. Suppose a base email schema is annotated, then a new schema is produced by adding a check or changing its wrapper. The new object may represent a different contract even if it started from the same field. Treating metadata as an identity-based association forces the tool to decide whether the new contract needs its own title, examples, or identifier. That is safer than copying documentation blindly and calling two different boundaries the same thing.
JSON Schema is a bridge, not a mirror
Zod 4 provides first-party conversion from a Zod schema to JSON Schema. JSON Schema is useful because many systems understand it: API description tools, OpenAPI workflows, form generators, and structured-output interfaces. A Zod object with a name and age can become a JSON Schema object with properties, required keys, and the corresponding additional-property behavior.