From harness-claude
Defines runtime-validated TypeScript schemas using z.object, primitives, enums, literals, and schema composition. Useful for validating API responses, form submissions, and environment variables.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:zod-schema-definitionThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Define runtime-validated TypeScript schemas with z.object, primitives, enums, literals, and schema composition
Define runtime-validated TypeScript schemas with z.object, primitives, enums, literals, and schema composition
npm install zodz namespace: import { z } from 'zod'z.string(), z.number(), z.boolean(), z.date(), z.bigint(), z.symbol()z.undefined(), z.null(), z.void(), z.any(), z.unknown(), z.never()z.object() to compose fields into a schema object — each key maps to a Zod type:import { z } from 'zod';
const UserSchema = z.object({
id: z.string().uuid(),
name: z.string().min(1),
email: z.string().email(),
age: z.number().int().positive().optional(),
role: z.enum(['admin', 'editor', 'viewer']),
createdAt: z.date(),
});
z.enum() for a fixed set of string literals — prefer over z.union([z.literal(...)]) for simple cases:const StatusSchema = z.enum(['active', 'inactive', 'pending']);
type Status = z.infer<typeof StatusSchema>; // 'active' | 'inactive' | 'pending'
z.literal() for exact value matching:const TrueSchema = z.literal(true);
const FortyTwoSchema = z.literal(42);
const HelloSchema = z.literal('hello');
const ProfileSchema = z.object({
bio: z.string().optional(), // string | undefined
avatar: z.string().nullable(), // string | null
website: z.string().nullish(), // string | null | undefined
});
const AddressSchema = z.object({
street: z.string(),
city: z.string(),
zip: z.string().regex(/^\d{5}$/),
});
const OrderSchema = z.object({
id: z.string().uuid(),
shippingAddress: AddressSchema,
billingAddress: AddressSchema.optional(),
});
.parse() to throw on failure, .safeParse() to handle errors gracefully:// Throws ZodError if invalid
const user = UserSchema.parse(rawData);
// Returns { success: true, data } or { success: false, error }
const result = UserSchema.safeParse(rawData);
if (result.success) {
console.log(result.data); // fully typed
} else {
console.error(result.error.issues);
}
export const UserSchema = z.object({ ... })
export type User = z.infer<typeof UserSchema>
Zod schemas are composable objects — they are not just validators, they are type constructors. Every schema carries both a runtime validator and a TypeScript type. The z.infer<typeof Schema> pattern eliminates the dual-maintenance problem of keeping an interface and a validator in sync.
Schema composition strategies:
z.object(). Good for simple models..extend() to add fields without re-defining the base. See zod-object-patterns.Primitive coercion:
Zod does not coerce by default. z.number().parse("42") throws. Use z.coerce.number() when input may be a string (e.g., URL query params, form fields):
const PageSchema = z.object({
page: z.coerce.number().int().positive().default(1),
limit: z.coerce.number().int().min(1).max(100).default(20),
});
Default values:
const ConfigSchema = z.object({
timeout: z.number().default(5000),
retries: z.number().default(3),
debug: z.boolean().default(false),
});
Recursive schemas:
For tree structures, use z.lazy():
type Category = {
name: string;
subcategories: Category[];
};
const CategorySchema: z.ZodType<Category> = z.lazy(() =>
z.object({
name: z.string(),
subcategories: z.array(CategorySchema),
})
);
When NOT to use Zod schema definition directly:
z.discriminatedUnion() (see zod-union-discriminated)zod-string-validation)zod-object-patterns)npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeUses Zod schemas as the single source of truth for runtime validation and TypeScript types. Validates API requests, environment variables, and form data.
Provides Zod schema validation patterns and TypeScript type inference for defining schemas, parsing data, validating forms, and runtime type checks with z.object, z.string, z.infer.