The Classic API is Zod's primary, method-chaining interface for defining and validating schemas. It provides an ergonomic, object-oriented API where validation constraints are applied through method calls that return new schema instances. This is the default API exposed when importing from "zod".
For the functional, tree-shakable alternative, see Mini API (zod/mini). For the shared core infrastructure used by both APIs, see Core Package (zod/v4/core).
The Classic API is built as a layer on top of the Core package, adding method-chaining convenience methods to the base schema types. Each schema type in the Classic API extends its corresponding Core type and implements the ZodType interface.
Sources: packages/zod/src/v4/classic/schemas.ts20-151 packages/zod/src/v4/core/schemas.ts174-184
The ZodType interface defined in packages/zod/src/v4/classic/schemas.ts20-151 serves as the foundation for all Classic API schemas. It extends the Core $ZodType interface and adds convenience methods for parsing, validation, transformation, and schema composition.
Sources: packages/zod/src/v4/classic/schemas.ts428-432 packages/zod/src/v4/classic/schemas.ts876-878 packages/zod/src/v4/core/api.ts62-71
Each schema type follows a two-stage initialization pattern defined in packages/zod/src/v4/classic/schemas.ts156-259 First, the Core constructor initializes the base schema structure and internal state. Then, the Classic constructor adds method-chaining capabilities and convenience APIs.
Sources: packages/zod/src/v4/classic/schemas.ts156-259 packages/zod/src/v4/core/schemas.ts185-315
The initialization process defined in packages/zod/src/v4/classic/schemas.ts156-259 attaches all methods to the instance, including parsing methods (.parse(), .safeParse()), chaining methods (.optional(), .nullable()), and refinement methods (.refine(), .superRefine()).
All methods in the Classic API return new schema instances rather than mutating existing ones. This is implemented through the .clone() method defined in packages/zod/src/v4/classic/schemas.ts187
Sources: packages/zod/src/v4/classic/schemas.ts171-185 packages/zod/src/v4/core/util.ts
Validation constraints are accumulated as checks in the schema definition. Each validation method adds a new check to the checks array by cloning the schema with an updated definition.
| Method Category | Example Methods | Implementation |
|---|---|---|
| String Validation | .min(), .max(), .regex(), .includes() | Adds check via schemas.ts301-310 |
| Number Validation | .gt(), .lt(), .positive(), .int() | Adds check via schemas.ts848-862 |
| String Transforms | .trim(), .toLowerCase(), .toUpperCase() | Adds overwrite check via schemas.ts313-317 |
| Type Wrappers | .optional(), .nullable(), .array() | Creates wrapper schema via schemas.ts217-222 |
Sources: packages/zod/src/v4/classic/schemas.ts289-318 packages/zod/src/v4/classic/schemas.ts841-874
The ZodString class provides extensive string validation and transformation capabilities.
Sources: packages/zod/src/v4/classic/schemas.ts261-318 packages/zod/src/v4/classic/schemas.ts320-426
The string format methods like .email(), .url(), and .uuid() are deprecated in favor of dedicated factory functions (schemas.ts323-390). These factory functions create specialized ZodStringFormat instances that inherit string validation capabilities.
| Factory Function | Schema Type | Validation |
|---|---|---|
z.email() | ZodEmail | Email format with customizable regex |
z.url() | ZodURL | URL with protocol/hostname validation |
z.uuid() | ZodUUID | UUID with optional version constraint |
z.guid() | ZodGUID | GUID (less strict than UUID) |
z.emoji() | ZodEmoji | Single emoji character |
z.jwt() | ZodJWT | JSON Web Token with algorithm check |
Sources: packages/zod/src/v4/classic/schemas.ts446-758
Sources: packages/zod/src/v4/classic/schemas.ts804-874 packages/zod/src/v4/classic/schemas.ts893-896
Number validation methods in schemas.ts841-874 use the check system to add constraints. The .int() method is marked as legacy, with z.int() as the preferred alternative (schemas.ts815-816).
Object schemas support property validation, shape manipulation, and strictness modes.
Sources: packages/zod/src/v4/classic/schemas.ts1266-1408 packages/zod/src/v4/classic/schemas.ts1410-1494
Object schemas are defined starting at schemas.ts1266 The .extend() method (schemas.ts1423-1426) allows adding or overwriting properties, while .safeExtend() (schemas.ts1428-1461) enforces type compatibility. The .pick() and .omit() methods (schemas.ts1463-1488) create new schemas with selected or excluded properties.
| Method | Unknown Keys Behavior | Use Case |
|---|---|---|
z.object() | Stripped (default) | Standard validation |
z.strictObject() | Error thrown | Strict input validation |
z.looseObject() | Passed through | Flexible data handling |
.catchall(schema) | Validated with schema | Typed catch-all properties |
Sources: packages/zod/src/v4/classic/schemas.ts1266-1292
Sources: packages/zod/src/v4/classic/schemas.ts1496-1549 packages/zod/src/v4/classic/schemas.ts1551-1615 packages/zod/src/v4/classic/schemas.ts1749-1802
Array schemas (schemas.ts1496-1549) validate each element and support size constraints. Tuple schemas (schemas.ts1551-1615) validate fixed-length arrays with specific types per position, optionally followed by a rest element.
The Classic API provides four main parsing methods, each with synchronous and asynchronous variants:
| Method | Return Type | Error Behavior | Use Case |
|---|---|---|---|
.parse() | Output | Throws ZodError | Known-valid data |
.safeParse() | SafeParseResult | Returns result object | User input validation |
.parseAsync() | Promise<Output> | Throws ZodError | Async validation |
.safeParseAsync() | Promise<SafeParseResult> | Returns result object | Async user input |
Sources: packages/zod/src/v4/classic/schemas.ts195-199 packages/zod/src/v4/classic/parse.ts1-117
Sources: packages/zod/src/v4/classic/parse.ts7-39 packages/zod/src/v4/core/schemas.ts273-299
The parsing implementation in parse.ts7-39 wraps the core validation pipeline. The .run() method in schemas.ts273-299 handles the execution of type checking and validation checks, with special handling for bidirectional transformations.
Sources: packages/zod/src/v4/classic/parse.ts119-133
The SafeParseResult type defined in parse.ts119-133 is a discriminated union that allows safe handling of validation results without try/catch blocks.
Sources: packages/zod/src/v4/classic/schemas.ts212-214 packages/zod/src/v4/classic/refine.ts1-123
The .refine() method (schemas.ts212) adds a validation function that returns a boolean or promise. The .superRefine() method (schemas.ts213) provides a context object for reporting multiple issues with custom paths.
Sources: packages/zod/src/v4/classic/schemas.ts114-116 packages/zod/src/v4/classic/schemas.ts2167-2199
The .transform() method (schemas.ts114-116) allows modifying validated data. It's implemented as a pipe to a ZodTransform schema (schemas.ts2167-2199).
Wrapper schemas modify the behavior of inner schemas without changing their validation logic.
Sources: packages/zod/src/v4/classic/schemas.ts1804-1868 packages/zod/src/v4/classic/schemas.ts1965-2051
| Feature | .default() | .prefault() |
|---|---|---|
| When applied | After validation | Before validation |
| Direction | Output (forward) | Input (both directions) |
| Use case | Set default for missing values | Pre-fill inputs |
| Implementation | schemas.ts2014-2051 | schemas.ts2053-2088 |
Sources: packages/zod/src/v4/classic/schemas.ts2014-2088
Sources: packages/zod/src/v4/classic/schemas.ts1617-1659 packages/zod/src/v4/classic/schemas.ts1661-1692
Union schemas (schemas.ts1617-1659) try each option until one succeeds. Discriminated unions (schemas.ts1661-1692) use a shared discriminator property for efficient matching.
Intersection schemas require data to satisfy both schemas simultaneously:
Sources: packages/zod/src/v4/classic/schemas.ts1694-1715
Sources: packages/zod/src/v4/classic/schemas.ts2090-2142
Codec schemas (schemas.ts2090-2142) define bidirectional transformations between input and output representations. The .encode() method transforms in the reverse direction from .parse().
Sources: packages/zod/src/v4/classic/schemas.ts2144-2165
The .pipe() method (schemas.ts2144-2165) chains two schemas where the output type of the first must match the input type of the second. This enables composing transformations: z.string().pipe(z.coerce.number()).
Sources: packages/zod/src/v4/classic/schemas.ts1053-1157
Enum schemas (schemas.ts1053-1157) validate against a fixed set of values. They support both array syntax and TypeScript enum objects. The .enum property provides a convenient object with all enum values.
| Factory | Validates | Example |
|---|---|---|
z.literal(value) | Single value | z.literal("admin") |
z.literal([...]) | Multiple values | z.literal(["a", "b"]) |
z.templateLiteral([...]) | Template pattern | z.templateLiteral(["id_", z.string()]) |
Sources: packages/zod/src/v4/classic/schemas.ts1034-1051 packages/zod/src/v4/classic/schemas.ts2296-2329
Sources: packages/zod/src/v4/classic/schemas.ts234-252
The .describe() and .meta() methods (schemas.ts234-252) register metadata in the global registry. This metadata can include descriptions, examples, and custom application-specific data.
Sources: packages/zod/src/v4/classic/schemas.ts43-50 packages/zod/src/v4/classic/schemas.ts189-192
Custom registries (schemas.ts43-50) enable type-safe metadata management with application-specific schemas and metadata types.
The Classic API includes built-in JSON Schema conversion:
| Method | Returns | Use Case |
|---|---|---|
.toJSONSchema() | JSON Schema object | OpenAPI, validation |
.toJSONSchema({target}) | Targeted schema | Specific spec version |
"~standard".jsonSchema.output() | Standard Schema format | Standard Schema spec |
Sources: packages/zod/src/v4/classic/schemas.ts37 packages/zod/src/v4/classic/schemas.ts158-164
The .toJSONSchema() method (schemas.ts164) converts Zod schemas to JSON Schema format, supporting multiple targets including JSON Schema 2020-12 and OpenAPI 3.0.
Coercion schemas automatically convert input values to the target type:
Sources: packages/zod/src/v4/classic/index.ts
Coercion uses JavaScript's built-in conversion functions before validation. This is useful for parsing form data or query parameters where values arrive as strings.
Sources: packages/zod/src/v4/classic/schemas.ts2482-2523
File schemas (schemas.ts2482-2523) validate File objects with checks for MIME type, size, and filename patterns.
Function schemas validate function signatures:
Sources: packages/zod/src/v4/classic/schemas.ts2565-2628
The function schema (schemas.ts2565-2628) validates both the input arguments and return value of functions, with support for async functions.
Sources: packages/zod/src/v4/classic/schemas.ts2708-2741
Custom schemas (schemas.ts2708-2741) allow arbitrary validation logic with optional type guard support for TypeScript type narrowing.
Sources: packages/zod/src/v4/core/errors.ts packages/zod/src/v4/classic/schemas.ts17-25
Error messages follow a precedence chain, with parameter-level messages taking highest priority. Error maps can be customized at schema definition, parse time, or globally.
| Feature | Classic API | Mini API |
|---|---|---|
| Import | import * as z from "zod" | import * as z from "zod/mini" |
| Style | Method chaining | Functional composition |
| Example | z.string().min(5) | z.string().check(z.minLength(5)) |
| Bundle Size | Larger (all methods) | Smaller (tree-shakable) |
| Ergonomics | More convenient | More explicit |
| Target Users | Application developers | Library authors |
Sources: packages/zod/src/v4/classic/schemas.ts packages/zod/src/v4/mini/schemas.ts
The Classic API prioritizes developer experience with convenient method chaining, while the Mini API prioritizes bundle size through functional composition. Both APIs use the same core validation engine and support identical validation capabilities.
Refresh this wiki