Zod schema validation patterns. Activated when working with form validation, API response validation, or React Hook Form integration.
From common-skillsnpx claudepluginhub dding-g/ddingg-claude-marketplace --plugin common-skillsThis skill uses the workspace's default tool permissions.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Optimizes cloud costs on AWS, Azure, GCP via rightsizing, tagging strategies, reserved instances, spot usage, and spending analysis. Use for expense reduction and governance.
Schema validation - core patterns only
import { z } from 'zod';
const userSchema = z.object({
name: z.string().min(1, 'Name is required'),
email: z.string().email('Invalid email format'),
age: z.number().optional(),
});
type User = z.infer<typeof userSchema>;
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
const schema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
type FormData = z.infer<typeof schema>;
function LoginForm() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
});
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('email')} />
{errors.email && <span>{errors.email.message}</span>}
</form>
);
}
const apiResponseSchema = z.object({
id: z.string(),
created_at: z.string(),
});
// safeParse: returns result object instead of throwing
const result = apiResponseSchema.safeParse(response);
if (!result.success) {
console.error('Invalid response:', result.error.flatten());
return null;
}
return result.data;
const signupSchema = z
.object({
password: z.string().min(8),
confirmPassword: z.string(),
})
.refine((data) => data.password === data.confirmPassword, {
message: 'Passwords do not match',
path: ['confirmPassword'],
});
const schema = z.discriminatedUnion('type', [
z.object({ type: z.literal('email'), email: z.string().email() }),
z.object({ type: z.literal('phone'), phone: z.string() }),
]);
const userSchema = z.object({
id: z.string(),
name: z.string(),
email: z.string(),
});
const createUserSchema = userSchema.omit({ id: true });
const updateUserSchema = userSchema.partial().required({ id: true });
| Principle | Description |
|---|---|
| Single source of truth | Type and validation in one place via z.infer |
| safeParse for APIs | Use safeParse at system boundaries |
| Keep it simple | transform, coerce, preprocess only when truly needed |