Zod is a popular TypeScript-first schema validation library that helps developers enforce runtime type safety. When working with Zod, two commonly used methods for validation are parse
and safeParse
. While both serve the same purpose—validating input data against a Zod schema—their behavior and use cases differ significantly. In this article, we'll break down these differences and help you determine when to use each method.
Understanding parse
The parse
method is the more straightforward of the two. It validates input data against the defined schema and either:
- Returns the parsed data if validation succeeds.
- Throws an error if validation fails.
Example Parse Usage
import { z } from "zod"; const userSchema = z.object({ name: z.string(), age: z.number(), }); const validData = { name: "Alice", age: 25 }; const invalidData = { name: "Alice", age: "twenty-five" }; // Successful validation const parsedData = userSchema.parse(validData); console.log(parsedData); // { name: "Alice", age: 25 } // Validation failure - throws an error const parsedInvalidData = userSchema.parse(invalidData); // Throws: ZodError: Expected number, received string
When to Use parse
- When you are certain the input data is valid and want to avoid handling validation errors.
- When you prefer exceptions to be thrown on invalid data.
- In scenarios where validation errors should halt execution (e.g., critical API request validation).
Understanding safeParse
Unlike parse
, safeParse
does not throw an error when validation fails. Instead, it returns an object with a success flag and either the parsed data (if validation is successful) or detailed error information (if validation fails).
Example SafeParse Usage
const result1 = userSchema.safeParse(validData); console.log(result1); // { success: true, data: { name: "Alice", age: 25 } } const result2 = userSchema.safeParse(invalidData); console.log(result2); /* { success: false, error: ZodError: [{ path: ["age"], message: "Expected number, received string" }] } */
When to Use safeParse
- When you want to handle validation errors gracefully without exceptions.
- In user input scenarios where invalid data should not break execution.
- For validating multiple inputs in a batch without stopping on the first failure.
- When logging or processing validation errors instead of throwing exceptions.
Key Differences: parse
vs safeParse
Feature | parse | safeParse |
---|---|---|
Returns | Validated data | { success: boolean, data?: T, error?: ZodError } |
On failure | Throws an error | Returns success: false with error details |
Use case | When validation must succeed, and errors should halt execution | When validation failures need handling without crashing |
Conclusion
Choosing between parse
and safeParse
depends on your use case:
- Use
parse
when you want strict validation that throws errors upon failure. - Use
safeParse
when you want to handle validation errors gracefully.
Understanding these methods will help you write safer and more predictable TypeScript applications using Zod. Whether you're building APIs, validating user input, or enforcing data structures, choosing the right approach will improve code reliability and error handling.