zod transform

Zod transform and pipe

Use Zod transform to reshape validated data, chain validation with pipe, and reach for z.codec when you need a reversible two-way transform in Zod 4.

Open the JSON to Zod converter

Quick answer: what does Zod transform do?

`.transform()` runs after validation and maps the parsed value into a new shape, which also changes the schema's inferred output type. Use `.pipe()` to validate the transformed value with a second schema, and use `z.codec()` in Zod 4 when the transform must be reversible.

Transform validated input

`.transform()` receives the already-validated value and returns whatever you map it to. The inferred output type follows the return value, so downstream code sees the reshaped data.

import * as z from "zod";

const TrimmedName = z.string().min(1).transform((value) => value.trim());

TrimmedName.parse("  Jane  "); // "Jane"

const Slug = z.object({ title: z.string() }).transform((value) => ({
  ...value,
  slug: value.title.toLowerCase().replace(/\s+/g, "-"),
}));

Validate the transformed value with pipe

When a transform produces a value you still need to validate, `.pipe()` passes the output into a second schema. This is the clean way to parse a string into a number and then enforce numeric rules.

const PositiveFromString = z
  .string()
  .transform((value) => Number(value))
  .pipe(z.number().int().positive());

PositiveFromString.parse("42"); // 42
PositiveFromString.safeParse("-3").success; // false

Reversible transforms with z.codec()

A plain transform is one-way: it cannot turn the output back into the input. Zod 4 adds `z.codec()` for two-way conversions, with `decode` and `encode` so you can serialize back to the original form.

const DateCodec = z.codec(z.iso.datetime(), z.date(), {
  decode: (isoString) => new Date(isoString),
  encode: (date) => date.toISOString(),
});

const parsed = DateCodec.decode("2026-06-17T00:00:00.000Z"); // Date
const serialized = DateCodec.encode(parsed); // ISO string

transform vs refine: which to use

These solve different problems. Reach for the one that matches your intent so the inferred type and error behavior stay predictable.

  • Use `.refine()` or `.superRefine()` to validate without changing the value.
  • Use `.transform()` to reshape the value when validation passes.
  • Use `.pipe()` when a transformed value needs another validation pass.
  • Use `z.codec()` when you need both decode and encode directions.

Reshaping data in Zod

ToolWhat it doesUse when
.transform()Maps validated input to a new output value and changes the inferred output type.You need the parsed result in a different shape than the input.
.pipe()Feeds the output of one schema into another for a second validation pass.You validate, transform, then validate the transformed value.
z.codec()Defines a reversible decode/encode transform (Zod 4).You need to convert in both directions, such as string to Date and back.

Use FrameworkKit to generate the starter code, then review the output before shipping it in production.

Generate with the JSON to Zod schema generator

Zod validation resources

JSON to Zod converter

Convert sample payloads into copy-ready Zod schemas and inferred TypeScript types in the browser.

JSON to Zod schema examples

Open realistic API and product payload examples before adapting the JSON to Zod schema output.

TypeScript to Zod Converter

Convert TypeScript interfaces and type aliases into Zod schemas when the source shape already lives in code.

Zod to JSON Schema Converter

Use the canonical online converter when an existing Zod schema needs JSON Schema, AJV, or OpenAPI output.

Validate API responses with Zod

Validate API responses, request bodies, and fetch boundaries with Zod schemas in TypeScript.

Zod parse vs safeParse

Choose between parse, safeParse, parseAsync, and safeParseAsync for TypeScript validation flows.

Zod safeParse

Validate unknown data without throwing, narrow the result type, and format safeParse errors.

Zod safeParse error messages

Format safeParse failures, field errors, and API validation responses in TypeScript.

Zod refine vs superRefine

Add custom validation, async checks, and field-level error paths after generating a starter schema.

Zod nativeEnum in Zod 4

Migrate z.nativeEnum patterns to z.enum, validate TypeScript enums, and avoid enum value mistakes.

Use JSON to Zod for form validation

Start from a submitted form payload, then add business rules such as email, length, and enum checks.

Zod to JSON Schema for OpenAPI

Publish Zod API schemas as OpenAPI-compatible contracts when teams need portable documentation.

ZodError flatten vs format

Shape validation errors with z.flattenError() for forms and z.treeifyError() for nested data in Zod 4.

Zod coerce for query params

Turn string query params and form fields into numbers, dates, and booleans, and avoid the coerce.boolean trap.

Zod email validation (z.email)

Validate emails with the top-level z.email() in Zod 4, add custom messages, and migrate off z.string().email().

Zod vs JSON Schema

Choose between TypeScript-first runtime validation and portable schema contracts.

Zod vs Yup vs Valibot

Compare TypeScript validation libraries for API boundaries, forms, server actions, and bundle tradeoffs.

FAQ

Does Zod transform change the output type?

Yes. The inferred output type follows what the transform returns, so `z.infer` reflects the reshaped value rather than the input.

What is the difference between transform and refine?

`refine` validates a value without changing it, while `transform` maps the validated value into a new shape and updates the output type.

How do I validate a value after transforming it?

Use `.pipe()` to feed the transform output into a second schema, for example `z.string().transform(Number).pipe(z.number().int())`.

How do I make a transform reversible?

Use `z.codec()` in Zod 4, which defines both `decode` and `encode` so you can convert in both directions, such as ISO string to Date and back.

Related tools