zod.literal
— a Zod schema that validates a single literal value or an array of literals, ensuring only specific allowed values pass validation.
It prevents invalid or unexpected values in forms, API requests, or configs, enforcing strict data contracts and reducing runtime errors.
Want to see it in action? Keep reading to explore practical examples, edge cases, and best practices for z.literal()
in Zod v4, so you can validate strings, numbers, booleans, and arrays safely and predictably.
Test It Yourself: Code Example
import { z } from "zod";
// Single literal
const status = z.literal("published");
status.parse("published"); // works
// status.parse("draft"); // throws error
// Multiple literals in Zod v4
const colors = z.literal(["red", "green", "blue"]);
colors.parse("green"); // works
// colors.parse("yellow"); // throws error
How Zod Literal Works
zod.literal
is a schema in Zod v4 that validates a single exact value or any value from an array of literals. It ensures that only the specified values pass validation, making your data type-safe and predictable.
Single Value Validation
const status = z.literal("published");
status.parse("published"); // works
status.parse("draft"); // throws error
The status
schema only allows the exact value "published"
.
status.parse("published")
passes because it matches the literal.status.parse("draft")
throws an error because"draft"
is not allowed.- Zod treats
z.literal
as strict and case-sensitive.
Multiple value validation (Zod v4):
const colors = z.literal(["red", "green", "blue"]);
colors.parse("green"); // works
colors.parse("yellow"); // throws error
The colors
schema allows only the literals "red"
, "green"
, or "blue"
.
colors.parse("green")
passes because it matches one of the allowed values.colors.parse("yellow")
throws an error because"yellow"
is not in the list.
Error Handling with Zod Literal
z.literal
throws a ZodError when a value does not match the expected literal(s). You can catch errors to handle validation gracefully or customize error messages for better user feedback.
const status = z.literal("published");
try {
status.parse("draft"); // Throws ZodError
} catch (e) {
console.error("Validation failed:", e.errors);
}
In the example, status.parse("draft")
throws a ZodError because "draft"
does not match the literal.
You can also customize error messages in Zod v4 by passing an errorMap
, and handle validation gracefully using safeParse()
instead of parse()
, which avoids exceptions and lets you check success programmatically.
Edge Cases with Zod Literals
While z.literal()
is great for strict value validation, there are a few special cases to keep in mind. Arrays of literals must use constant references, empty arrays always fail, and objects don’t work as expected due to reference equality checks.
Understanding these nuances ensures your schemas remain predictable and error-free.
Arrays:
// Normal array from existing values
const allowedColors = ["red", "green", "blue"] as const;
const colors = z.literal(allowedColors);
colors.parse("green"); // works
colors.parse("yellow"); // throws error
// Empty array edge case
const emptyLiteral = z.literal([]);
emptyLiteral.parse(undefined); // throws error
In this code example, there are two cases. The first creates a colors
schema from an array of allowed values, validating only inputs that match the predefined items in allowedColors
.
The second case demonstrates an empty array edge case. Since no values are allowed, any input—including undefined
—fails validation.
Boolean:
const isPublished = z.literal(true);
isPublished.parse(true); // works
isPublished.parse(false); // throws error
In this example, the isPublished
schema only accepts true
. Any other value, including false
, fails validation. This ensures that a boolean field strictly matches the expected literal value.
Number:
const maxItems = z.literal(5);
maxItems.parse(5); // works
maxItems.parse(3); // throws error
The maxItems
schema only accepts the number 5
. Any other number, such as 3
, fails validation. This ensures that a numeric field strictly matches the expected literal value.
Object:
const defaultConfig = z.literal({ theme: "dark", layout: "grid" });
defaultConfig.parse({ theme: "light", layout: "grid" }); // throws error
z.literal
does not work with objects as expected because it checks exact reference equality, not the contents. Even if a new object has the same keys and values, it fails validation. For object validation, use z.object()
instead.
Summary
z.literal()
in Zod validates one exact value (or multiple in Zod v4 using an array). It ensures only specific allowed values pass validation, enforcing strict data contracts and preventing unexpected inputs in forms, APIs, or configs.
It’s case-sensitive and checks equality strictly for strings, numbers, or booleans. When using arrays, only predefined items are accepted. Objects don’t work because Zod checks reference equality — use z.object()
instead.
z.literal()
is just one part of Zod’s powerful validation system. To understand all Zod schemas and best practices, check out our complete guide to Zod schema validation.