Prompt directory
Impulse.directory
HomeBrowseStacks
Sign inCreate an account
    rule

    Zod best practices

    impulse-lab/zod-best-practices·v1·updated September 25, 2025
    Leonard Roussard
    Leonard Roussard@lionvsx·Impulse Lab
    Cursor / Rules
    Content
    ---
    description: Best practices for using Zod for schema validation
    globs:
    alwaysApply: false
    ---
    
    # Zod Best Practices
    Standards for using Zod schema validation. Auto-included for TypeScript and TSX files.
    <rule>
    name: zod_best_practices
    description: Best practices for using Zod for schema validation. Auto-included for TypeScript and TSX files.
    globs: ["**/*.{ts,tsx}"]
    filters:
    - type: file_extension
    pattern: "\.(ts|tsx)$"
    actions:
    - type: suggest
    message: |
    Follow these Zod best practices:
        1. Schema Definition:
            - Define clear and descriptive schemas
            - Use proper type inference
            - Implement proper validation rules
            - Use schema composition
        2. Validation Implementation:
            - Use proper error handling
            - Implement custom validation logic
            - Use refinements when needed
            - Handle async validation properly
        3. Type Integration:
            - Use infer types from schemas
            - Implement proper type safety
            - Use proper type coercion
            - Handle optional fields properly
        4. Form Integration:
            - Use with React Hook Form
            - Implement proper form validation
            - Handle form submission properly
            - Use proper error messages
        5. API Integration:
            - Validate API responses
            - Implement request validation
            - Handle validation errors
            - Use proper error messages
        6. Validator Organization:
            - Place validators not linked to database schemas in the `/validators` folder
            - Organize by feature or domain:
            - `/validators
      /auth
        register.ts
        login.ts
      /user
        profile.ts
        settings.ts
      /forms
        contact.ts
        feedback.ts
    `
            - For database-related validators, use Drizzle Zod integration:
            - `// For DB schema validators
    import { createInsertSchema } from 'drizzle-zod';
    import { users } from '@/server/db/schema';
    
    export const insertUserSchema = createInsertSchema(users);
    
    // For non-DB validators (in /validators folder)
    // /validators/forms/contact.ts
    import { z } from 'zod';
    
    export const contactFormSchema = z.object({
      name: z.string().min(2, "Name must be at least 2 characters"),
      email: z.string().email("Invalid email format"),
      message: z.string().min(10, "Message must be at least 10 characters"),
    });
    
    export type ContactFormValues = z.infer<typeof contactFormSchema>;
    `
            - Export type definitions alongside schemas
            - Create and export error handling utilities for Zod errors
    examples:
    - input: |
    // Bad: Not using Zod for type safety
    interface User {
    name: string;
    age: number;
    email: string;
    }
    - // Good: Using Zod schema with validation
    const UserSchema = z.object({
    name: z.string().min(2),
    age: z.number().min(0).max(120),
    email: z.string().email()
    });
    - type User = z.infer<typeof UserSchema>;
    output: "Use Zod schemas for runtime validation and type inference"
    - input: |
    // Bad: Manual validation
    function validateEmail(email: string) {
    return email.includes('@');
    }
    - // Good: Using Zod refinements
    const EmailSchema = z.string().email().refine(
    async (email) => {
    const isUnique = await checkEmailUnique(email);
    return isUnique;
    },
    {
    message: "Email already exists"
    }
    );
    output: "Use Zod refinements for custom validation logic"
    - input: |
    // Bad: Not organizing validators properly
    // Scattered across different files
    - // components/contact-form.tsx
    const contactSchema = z.object({
    name: z.string(),
    email: z.string().email(),
    message: z.string()
    });
    - // app/page.tsx
    const searchParamsSchema = z.object({
    q: z.string().optional(),
    page: z.coerce.number().default(1)
    });
    - // Good: Organized validators
    // /validators/forms/contact.ts
    export const contactSchema = z.object({
    name: z.string().min(2, "Name must be at least 2 characters"),
    email: z.string().email("Invalid email format"),
    message: z.string().min(10, "Message must be at least 10 characters")
    });
    - export type ContactForm = z.infer<typeof contactSchema>;
    - // /validators/search-params.ts
    export const searchParamsSchema = z.object({
    q: z.string().optional(),
    page: z.coerce.number().default(1),
    sortBy: z.enum(["date", "name", "relevance"]).default("relevance")
    });
    - export type SearchParams = z.infer<typeof searchParamsSchema>;
    output: "Organize validators in the /validators folder by feature"
    metadata:
    priority: high
    version: 1.1
    </rule>

    Install with the impulse CLI

    $npx @impulselab/directory impulselab/zod-best-practices

    Stats

    Views
    20
    Saves
    0

    Owner

    impulse-logo

    Impulse Lab

    Official artifact