This document covers the codec system in Zod, which enables bidirectional transformations between two schema types. Codecs provide a way to convert data in both directions: from an input representation to an output representation (decode), and from output back to input (encode). This is particularly useful for serialization boundaries such as network communication, where data must be converted between a wire format (e.g., JSON strings) and a richer in-memory representation (e.g., Date objects).
For unidirectional transformations, see Transformations and Preprocessing. For information on default value handling, see Default and Prefault Values.
Sources: packages/docs/content/codecs.mdx1-50
A codec encapsulates a transformation between two schema types with operations in both directions:
Diagram: Bidirectional transformation flow in codecs
The codec maintains two schemas and two transformation functions that must be inverse operations of each other.
Sources: packages/docs/content/codecs.mdx49-86
All Zod schemas can process inputs in both forward and backward directions. In most schemas, the input and output types are identical, but z.codec() specifically diverges them.
| Operation | Direction | Schema Sequence | Type Safety |
|---|---|---|---|
.parse() | "forward" | Input → Output | Accepts unknown |
.decode() | "forward" | Input → Output | Strongly typed input |
.encode() | "backward" | Output → Input | Strongly typed input |
Sources: packages/docs/content/codecs.mdx11-18 packages/docs/content/codecs.mdx111-135
Diagram: Type signatures for parsing, decoding, and encoding operations
The .parse() method defined in ZodType packages/zod/src/v4/classic/schemas.ts115 accepts unknown input for maximum flexibility, while .decode() packages/zod/src/v4/classic/schemas.ts129 and .encode() packages/zod/src/v4/classic/schemas.ts128 have strongly-typed inputs to surface compile-time errors when transforming already-typed data.
Sources: packages/docs/content/codecs.mdx112-135 packages/zod/src/v4/classic/schemas.ts115-148
The z.codec() function creates a bidirectional schema. Codecs are implemented internally using the $ZodCodec constructor packages/zod/src/v4/classic/tests/codec.test.ts17
Sources: packages/zod/src/v4/classic/tests/codec.test.ts4-11 packages/docs/content/codecs.mdx189-191
The ZodType interface in the Classic API packages/zod/src/v4/classic/schemas.ts78-148 and the ZodMiniType in the Mini API packages/zod/src/v4/mini/schemas.ts7-38 provide methods for working with codecs.
| Method | Sync | Type | Returns |
|---|---|---|---|
.parse(data) | ✓ | Throws | Output |
.decode(data) | ✓ | Throws | Output |
.encode(data) | ✓ | Throws | Input |
.safeParse(data) | ✓ | Safe | ZodSafeParseResult<Output> |
.safeDecode(data) | ✓ | Safe | ZodSafeParseResult<Output> |
.safeEncode(data) | ✓ | Safe | ZodSafeParseResult<Input> |
.parseAsync(data) | ✗ | Throws | Promise<Output> |
.decodeAsync(data) | ✗ | Throws | Promise<Output> |
.encodeAsync(data) | ✗ | Throws | Promise<Input> |
.safeParseAsync(data) | ✗ | Safe | Promise<ZodSafeParseResult<Output>> |
.safeDecodeAsync(data) | ✗ | Safe | Promise<ZodSafeParseResult<Output>> |
.safeEncodeAsync(data) | ✗ | Safe | Promise<ZodSafeParseResult<Input>> |
Sources: packages/zod/src/v4/classic/schemas.ts115-148 packages/docs/content/codecs.mdx147-161 packages/zod/src/v4/core/parse.ts97-185
The internal validation engine uses a direction flag in the ParseContext packages/zod/src/v4/core/parse.ts104 to determine which transformation path to execute.
Diagram: High-level direction-aware validation flow
In the backward direction, _encode calls _parse with the direction: "backward" context packages/zod/src/v4/core/parse.ts103-106
Sources: packages/docs/content/codecs.mdx195-213 packages/zod/src/v4/core/parse.ts97-133
Use z.invertCodec() to derive the reverse codec from an existing one. This swaps the input and output schemas and their respective transforms packages/docs/content/codecs.mdx95-124
Sources: packages/docs/content/codecs.mdx95-124
Sources: packages/zod/src/v4/classic/tests/codec.test.ts4-11
Sources: packages/zod/src/v4/classic/tests/codec.test.ts126-130
In the Classic API, ZodCodec inherits from ZodPipe packages/zod/src/v4/classic/tests/codec.test.ts15 In the Mini API, ZodMiniCodec follows a similar hierarchy packages/zod/src/v4/mini/tests/codec.test.ts17-19
Diagram: Inheritance hierarchy for Codecs across API variants
Sources: packages/zod/src/v4/classic/tests/codec.test.ts13-19 packages/zod/src/v4/mini/tests/codec.test.ts16-22
Codecs support asynchronous transformations. If transforms are async, methods like decodeAsync packages/zod/src/v4/classic/schemas.ts131 or safeEncodeAsync packages/zod/src/v4/classic/schemas.ts143 must be used.
Sources: packages/docs/content/codecs.mdx137-161 packages/zod/src/v4/classic/tests/codec.test.ts141-169 packages/zod/src/v4/core/parse.ts122-185
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.