In Zod v4 , metadata and registries form powerful complementary systems that let developers annotate schemas with additional information and organize them for discovery and tooling support.
They don’t interfere with validation logic, but rather enrich your schemas to serve purposes like documentation, code generation, or schema sharing across modules.
What are Registries in Zod?
Registries in Zod are collections of schemas, each linked with strongly-typed metadata. You begin by creating a registry via z.registry<MetaType>()
, where MetaType
defines what kind of metadata entries can be associated.
For example:
const myRegistry = z.registry<{ description: string }>();
You can then add, check, get, remove, or clear schema entries in this registry.
Eg, adding a schema:
myRegistry.add(mySchema, { description: "A cool schema!" });
TypeScript ensures that only metadata matching the declared MetaType
is allowed. Also, registries handle schema IDs specially: if two schemas share the same id
in the same registry, an error is thrown.
Schema-Side Registration via .register() in Zod
Instead of separately adding schemas via the registry API, each schema in Zod exposes a .register()
method, which associates that schema instance with a registry and metadata in one call. This method returns the original schema (unlike .meta()
or .describe()
which create new schema instances).
This inline registration is helpful to keep schema definitions concise and tightly scoped with their metadata, useful for form generation, input validation UIs, documentation, etc.
Global Registry & Metadata
Zod allows you to add metadata to schemas.
Zod offers a global registry via z.globalRegistry
. This is particularly useful when you want shared schema metadata, like JSON Schema generation, API documentation, or other tools that need to read metadata across schemas.
The global registry uses a built-in GlobalMeta
interface, which includes optional fields like id
, title
, description
, deprecated
, etc. You can also extend this via TypeScript’s module augmentation to add custom fields.
.meta() and .describe(): Schema Metadata Methods
.meta()
is the recommended method to associate metadata with a schema instance. When you call.meta({ ... })
, the metadata is registered in thez.globalRegistry
for that schema. If you call.meta()
with no arguments, it returns existing metadata (if any)..describe()
is a shorthand for adding adescription
field only; it’s retained for compatibility with older Zod versions. Essentially.describe("text")
is equivalent to.meta({ description: "text" })
.
Why Use Metadata & Registries?
Metadata and registries are indispensable in medium-to-large projects for:
- Generating documentation automatically from schemas.
- Building UI forms where each field needs label/description or example.
- JSON schema generation or schema export for API clients.
- Centralizing schema discovery: tools can scan registries to find all relevant schemas.
- Enforcing consistency (e.g. ensuring schema IDs are unique, quality of metadata).
Because metadata doesn’t impact how data is validated, it keeps the runtime semantics pure and predictable. Tools that read metadata do so in separate layers (docs, UI, dev tooling), preserving separation between validation logic and descriptive annotations.
Conclusion
Metadata and registries in Zod are not about changing how validation works — they’re about enriching and organizing your schemas. Metadata gives you a way to attach helpful annotations like descriptions, tags, or examples, while registries allow you to collect, reference, and share schemas across your project.
Together, they unlock advanced possibilities such as automatic documentation, UI generation, and schema discovery without complicating your core validation logic.
For developers building scalable applications, mastering metadata and registries ensures you get the most out of Zod’s ecosystem while keeping your codebase clean, maintainable, and future-ready.