.claude/skills/zod/SKILL.md
Zod schema validation and TypeScript integration for runtime type safety. Use when: Validating API payloads, form inputs, environment variables, or any external data boundaries where TypeScript types alone cannot guarantee safety.
npx skillsauth add kaxuna1/ecomsite zodInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Runtime validation library for TypeScript. Use at system boundaries where data enters your application: API responses, form inputs, environment variables, URL params, localStorage. TypeScript types disappear at runtime—Zod provides the actual validation.
# Frontend
cd frontend && npm install zod @hookform/resolvers
# Backend
cd backend && npm install zod
import { z } from 'zod';
// Define schema
const ProductSchema = z.object({
id: z.number(),
name: z.string().min(1),
price: z.number().positive(),
salePrice: z.number().positive().nullable(),
categories: z.array(z.string()),
isNew: z.boolean().default(false),
});
// Infer TypeScript type from schema
type Product = z.infer<typeof ProductSchema>;
// Validate data
const product = ProductSchema.parse(apiResponse); // throws on invalid
const result = ProductSchema.safeParse(data); // returns { success, data/error }
| Concept | Usage | Example |
|---------|-------|---------|
| .parse() | Throws ZodError on failure | schema.parse(data) |
| .safeParse() | Returns result object | { success: boolean, data?, error? } |
| z.infer<> | Extract TS type from schema | type User = z.infer<typeof UserSchema> |
| .transform() | Modify value after validation | .transform(s => s.toLowerCase()) |
| .refine() | Custom validation logic | .refine(n => n % 2 === 0, 'Must be even') |
Replace the current manual validation in backend/src/config/env.ts:
import { z } from 'zod';
const envSchema = z.object({
PORT: z.coerce.number().default(4000),
DB_HOST: z.string().default('localhost'),
DB_PORT: z.coerce.number().default(5432),
DB_NAME: z.string().default('luxia'),
DB_USER: z.string().default('postgres'),
DB_PASSWORD: z.string().min(1, 'DB_PASSWORD is required'),
JWT_SECRET: z.string().min(32, 'JWT_SECRET must be at least 32 chars'),
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
});
export const env = envSchema.parse(process.env);
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
const checkoutSchema = z.object({
name: z.string().min(2, 'Name is too short'),
email: z.string().email('Invalid email'),
phone: z.string().optional(),
address: z.string().min(10, 'Address is required'),
});
type CheckoutForm = z.infer<typeof checkoutSchema>;
const { register, handleSubmit, formState: { errors } } = useForm<CheckoutForm>({
resolver: zodResolver(checkoutSchema),
});
tools
Zustand lightweight state management with persistence and middleware. Use when: managing client-side state (cart, auth, UI preferences), replacing React Context with simpler API, accessing state outside React components, implementing localStorage persistence
tools
Configures Vite 5.x build tool, dev server, and frontend asset optimization for the Luxia e-commerce platform. Use when: configuring builds, adding environment variables, optimizing bundle size, setting up testing, debugging HMR issues, or adding Vite plugins.
development
Enforces strict TypeScript types across frontend and backend codebases. Use when: Writing new services, DTOs, interfaces, type guards, debugging type errors, or ensuring type safety at API boundaries.
development
Manages server state, API caching, and data fetching with TanStack React Query v5. Use when: Fetching API data, managing server state, polling for updates, handling mutations with cache invalidation.