DEV Community

Cover image for Zod 4 - From Validation to Data Pipelines
Hugo Campañoli
Hugo Campañoli

Posted on • Edited on • Originally published at campa.dev

Zod 4 - From Validation to Data Pipelines

Validating that a field exists is the floor, not the ceiling. Your CMS or API data is often "dirty": dates as strings, empty tags, non-normalized slugs. If you clean this up in your components, you're duplicating logic that Zod 4 can solve in a single schema.

In this guide, we'll see how to transform your validation into a pure data pipeline.

From Validator to Transformation Pipeline

Look at the difference between a schema that only validates and one that transforms, normalizes, and performs cross-field validation:

// Advanced Schema — Validate + Transform + Normalize
const blogSchema = z.object({
  title: z.string().trim(),
  slug: z.string()
    .transform((s) => s.toLowerCase().replace(/\s+/g, "-")),
  publishedAt: z.string()
    .transform((s) => new Date(s)),
  tags: z.array(z.string())
    .transform((arr) => arr.filter(Boolean)),
}).superRefine((data, ctx) => {
  if (data.publishedAt > new Date()) {
    ctx.addIssue({
      code: "custom",
      message: "Date cannot be in the future",
      path: ["publishedAt"],
    });
  }
});
Enter fullscreen mode Exit fullscreen mode

The Three Patterns You Need to Know

1. .transform() — Modify data after validation
Change the output type directly in the schema.

2. .superRefine() — Cross-field validation
Perfect for complex rules like "Published articles require a date, but drafts don't".

3. .prefault() — The new Zod 4 pre-parse default
In Zod 4, .default() applies after the transform. Use .prefault() if you need the default value to pass through your transformation pipeline (Zod 3 behavior).


Where should the logic go?

  • In the Schema (Zod): Single source of truth, automatic output typing, zero boilerplate in UI.
  • In Components: Dispersed logic, harder to test, and redundant.

Validating is easy. Transforming with elegance is the art of a Senior Engineer.


Originally published at: campa.dev

Top comments (0)