Zod Default by Type: Practical Examples for Every Schema


Zod String Default: Set Default for Text Fields

A Zod string default helps ensure that text fields always return a defined value, even when the user input is missing. This is useful for setting defaults like “guest”, “light”, or “en” in forms, profiles, or settings.

import { z } from 'zod';
const userProfileSchema = z.object({
username: z.string().default('guest_user'),
});
userProfileSchema.parse({});
// ➜ { username: 'guest_user' }

This guarantees that if username is left out, it automatically resolves to ‘guest_user’, making your data consistent and UI fallback-proof.

Zod Number Default: Handle Numeric Defaults in Zod

A Zod number default ensures your numeric fields never return undefined, especially in cases like counters, limits, ratings, or pagination values. It’s commonly used to set defaults such as 0, 1, or 100 for fields like retry attempts, page numbers, or quantity selectors.

import { z } from 'zod';

const apiConfigSchema = z.object({
retryCount: z.number().default(3),
});

apiConfigSchema.parse({});
// ➜ { retryCount: 3 }

This guarantees stability when the client omits retryCount, making your API configuration more predictable and fault-tolerant.

Zod Boolean Default: True/False with Safe Defaults

A Zod boolean default is perfect for toggles, flags, and switches—where you want a guaranteed true or false value, even if the user skips the input. It’s commonly used for settings like email notifications, feature toggles, dark mode, or terms agreement.

import { z } from 'zod';

const settingsSchema = z.object({
emailNotifications: z.boolean().default(true),
});

settingsSchema.parse({});
// ➜ { emailNotifications: true }

This ensures consistent behavior in your UI and backend logic, eliminating unexpected undefined values in binary decision fields.

Zod Array Default: Provide Default Empty or Pre-Filled Arrays

A Zod array default is useful when you expect an array input—like tags, categories, selected options—but want to avoid dealing with undefined or null. By assigning a default array (empty or pre-filled), you ensure safe iteration and predictable data structures.

import { z } from 'zod';

const articleSchema = z.object({
tags: z.array(z.string()).default([]),
});

articleSchema.parse({});
// ➜ { tags: [] }

This approach is especially helpful in forms, filters, and API payloads where an empty array is more meaningful and less error-prone than an undefined value.

Zod Object Default: Fallbacks for Complex Structures

A Zod object default provides a complete fallback when an entire nested object is missing. It’s especially useful in settings, preferences, or form sections where groups of fields may be skipped but need default behavior.

import { z } from 'zod';

const notificationSchema = z.object({
email: z.boolean().default(true),
sms: z.boolean().default(false),
});

const userSchema = z.object({
notifications: notificationSchema.default({}),
});

userSchema.parse({});
// ➜ { notifications: { email: true, sms: false } }

This ensures that even when the full notifications object is omitted, Zod fills it with safe defaults—preventing null errors and reducing fallback logic in your app.

Zod Enum and Literal Default: Default Matching for Known Values

A Zod enum or literal default allows you to preselect a known, fixed value when no input is provided. This is ideal for fields like user roles, app themes, language codes, or consent statuses—where only a limited set of values is valid, and one should be the fallback.

import { z } from 'zod';

const roleSchema = z.enum(['admin', 'editor', 'viewer']).default('viewer');

roleSchema.parse(undefined);
// ➜ 'viewer'

This guarantees that even without user input, the field aligns with valid options—eliminating invalid states and ensuring type safety across your application.

If you’re new to enums or want to explore more ways to define them, see our full guide on working with z.enum.

Zod Date Default: Current Date or Fixed Date Defaults

A Zod date default is perfect when you need to auto-fill timestamps like createdAt, publishedOn, or startDate. Zod supports both fixed dates and dynamic defaults using functions—commonly used to insert the current date and time.

import { z } from 'zod';

const postSchema = z.object({
createdAt: z.date().default(() => new Date()),
});

postSchema.parse({});
// ➜ { createdAt: [current date object] }

Using dynamic defaults ensures every validated object has a reliable timestamp—without relying on client input or extra backend logic.

Zod Null and Undefined Defaults: Handling Absence Gracefully

Zod allows you to define defaults when a field is explicitly undefined, but it won’t apply them if the input is null—unless you explicitly allow it. To handle both cases, combine .nullable() or .optional() with .default(). This is especially useful for optional descriptions, optional images, or fields that support clearing input.

import { z } from 'zod';

const profileSchema = z.object({
avatar: z.string().nullable().default(null),
});

profileSchema.parse({});
// ➜ { avatar: null }

This ensures the field is always present—even if it’s intentionally empty—making it easier to work with UI components and APIs that expect consistent keys.

Sharukhan Avatar

Sharukhan Patan

Sharukhan Patan is the founder of Tecktol. He has worked as a software engineer specializing in full-stack web development.