Capítulo 26 de 61

Chapter 26: Codecs — Basics

Core Idea

A codec (zod@4.1+) is a bidirectional transform between two schemas: .decode()/.parse() runs the forward transform (input schema → output schema), .encode() runs the reverse.

Key Concepts

  • z.codec(inputSchema, outputSchema, { decode, encode }): pairs an input schema, an output schema, and the two conversion functions between them.
  • .parse() on a codec: runs the forward transform — equivalent to decode.
  • z.decode(codec, input): like .parse() but expects strongly-typed input (matching the input schema's type) rather than unknown.
  • z.encode(codec, output): runs the reverse transform, turning an output-shaped value back into the input shape.
  • z.invertCodec(codec): derives a new codec with input/output (and decode/encode) swapped.

Code Examples

const stringToDate = z.codec(
  z.iso.datetime(), // input schema: ISO date string
  z.date(),         // output schema: Date object
  {
    decode: (isoString) => new Date(isoString),
    encode: (date) => date.toISOString(),
  }
);

stringToDate.parse("2024-01-15T10:30:00.000Z"); // => Date
z.decode(stringToDate, "2024-01-15T10:30:00.000Z"); // => Date (strongly-typed input)
z.encode(stringToDate, new Date("2024-01-15"));     // => ISO string

const dateToString = z.invertCodec(stringToDate);
z.decode(dateToString, new Date("2024-01-15")); // => string
  • What it demonstrates: defining a codec, running it both directions, and inverting it.

Key Takeaways

  1. Reach for a codec (not a plain .transform()) whenever you need to go both directions between two representations — e.g. parsing an ISO string to a Date and later serializing that Date back to a string.
  2. .parse()/z.decode() and z.encode() are the forward and reverse operations respectively; z.invertCodec() flips which direction is "forward."
  3. Zod ships copy-paste-ready codec recipes on its dedicated Codecs docs page (string↔number, string↔bigint, ISO datetime↔Date, epoch seconds/millis↔Date, JSON codec, UTF-8/base64/hex↔bytes, string↔URL, string↔boolean) — check there before writing one from scratch.

Connects To

  • Pipes: z.input()/z.output() reach into codecs nested inside objects/records/maps.
  • Transforms: the one-directional counterpart — use transforms when you never need to go back to the original shape.