Zod coerce for query params and forms
Use z.coerce.number(), z.coerce.boolean(), and z.coerce.date() to turn string query params and form fields into typed values, and avoid the z.coerce.boolean() truthy trap with z.stringbool() in Zod 4.
Quick answer: how do you turn a string param into a number with Zod?
Wrap the field in `z.coerce.number()`. Query strings, route params, form fields, and env vars all arrive as strings, and coercion runs a JavaScript cast before validation so the parsed output is correctly typed. Use `z.coerce.date()` for dates, but avoid `z.coerce.boolean()` for flags because it treats any non-empty string as true.
Coerce numbers from query strings
A pagination or filter query gives you strings. `z.coerce.number()` casts before validating, so you can still chain `.int()`, `.min()`, and `.max()` to keep the value in range.
import * as z from "zod";
const QuerySchema = z.object({
page: z.coerce.number().int().min(1).default(1),
pageSize: z.coerce.number().int().max(100).default(20),
});
QuerySchema.parse({ page: "3", pageSize: "50" });
// { page: 3, pageSize: 50 }Coerce dates safely
`z.coerce.date()` runs `new Date(value)` and rejects values that produce an Invalid Date. This is convenient for URL filters, but validate the range afterward if only certain dates are allowed.
const RangeSchema = z.object({
from: z.coerce.date(),
to: z.coerce.date(),
});
const range = RangeSchema.parse({
from: "2026-01-01",
to: "2026-06-30",
});
// { from: Date, to: Date }The z.coerce.boolean() trap (and z.stringbool fix)
`z.coerce.boolean()` calls `Boolean(value)`. Because any non-empty string is truthy, the string "false" becomes `true`. For real query-string flags, use `z.stringbool()` in Zod 4, which understands "true"/"false", "1"/"0", and "yes"/"no".
// Trap: "false" is a non-empty string -> true
z.coerce.boolean().parse("false"); // true
// Fix in Zod 4
z.stringbool().parse("false"); // false
z.stringbool().parse("yes"); // trueWhere coercion belongs
Coercion is for boundaries where data arrives as text. Keep it out of your internal domain models, which should already hold typed values.
- Use coercion for URL query params, route params, form submissions, env vars, and CSV cells.
- Do not coerce inside internal types that already hold numbers, dates, or booleans.
- Combine coercion with `safeParse` so bad params return a structured error instead of throwing.
- Prefer `z.stringbool()` over `z.coerce.boolean()` for any string flag.
Zod coercion helpers
| Helper | Behavior | Use when |
|---|---|---|
| z.coerce.number() | Runs `Number(value)` before validating, so "42" becomes 42 and "" becomes 0. | Numeric query params or form fields that arrive as strings. |
| z.coerce.boolean() | Runs `Boolean(value)`, so ANY non-empty string is `true`, including "false". | Rarely what you want for query strings; prefer z.stringbool() for real flags. |
| z.coerce.date() | Runs `new Date(value)` and validates the result is a valid date. | Date params from URLs, form inputs, or CSV imports. |
| z.stringbool() | Parses "true"/"false", "1"/"0", "yes"/"no" into a real boolean (Zod 4). | Boolean flags coming from query strings or env vars. |
Use FrameworkKit to generate the starter code, then review the output before shipping it in production.
Generate with the JSON to Zod schema generatorZod 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 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 transform and pipe
Reshape validated data with transform, chain a second check with pipe, and use z.codec for reversible conversions.
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
How do I convert a string to a number in Zod?
Use `z.coerce.number()`. It runs `Number(value)` before validation, so "42" parses to 42, and you can still chain `.int()`, `.min()`, and `.max()`.
Why does z.coerce.boolean() return true for "false"?
It calls `Boolean(value)`, and any non-empty string is truthy. Use `z.stringbool()` in Zod 4 to parse "true"/"false" and similar strings into the correct boolean.
Does z.coerce.date() handle invalid dates?
Yes. It runs `new Date(value)` and rejects values that produce an Invalid Date. Validate the date range separately if only certain dates are allowed.
Should I coerce values everywhere?
No. Apply coercion only at boundaries where data arrives as strings, such as query params and forms. Internal models should already hold typed values.
Related tools
TypeScript to Zod Converter
Convert TypeScript interfaces and type aliases into Zod schemas with inferred types in your browser.
Zod to JSON Schema Converter
Use a free browser-only online converter to turn Zod 4 schemas into JSON Schema for Draft 2020-12, Draft 7, AJV, or OpenAPI-compatible output.
OpenAPI to Zod
Turn OpenAPI schemas into Zod validators and lightweight typed fetch clients.