Agent skill

Zod Patterns

by shepherdjerred in shepherdjerred/monorepo

Zod schema validation, type-safe development, and strict TypeScript patterns.

GPL-3.0Auto-check passedFrontend & Design

Install Zod Patterns

skills CLI
$ npx skills add shepherdjerred/monorepo --skill zod-patterns -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install shepherdjerred/monorepo zod-patterns --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/shepherdjerred/monorepo.git skills-src && mkdir -p .claude/skills && cp -r skills-src/packages/dotfiles/dot_agents/skills/zod-patterns .claude/skills/zod-patterns && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
zod-patterns
GitHub stars
112
Token cost
~5k tokens
SKILL.md length
382 words
Files
1
Skills in repo
63
Repo updated
First seen
Licence
GPL-3.0

At a glance

Zod schema validation, type-safe development, and strict TypeScript patterns.

  • Works in 10 steps: Use safeParse() - avoid throwing in… → Infer types - let Zod generate… → Compose schemas - use extend, pick, omit… → …
  • Creates schemas
  • SKILL.md covers What's New in Zod 4 (2025), Installation, Basic Usage and Primitive Types, plus 6 more sections
  • Calls bun; needs API_KEY

What it does

Zod Patterns is an agent skill from shepherdjerred/monorepo. Zod schema validation, type-safe development, and strict TypeScript patterns. When user works with Zod, validates data, creates schemas, handles form validation, mentions z.object/z.string patterns, needs runtime validation, type-safe code, or strict TypeScript configuration.

Its SKILL.md is about 5k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Frontend & Design, covering Forms and validation. It works with Zod and TypeScript. The repository describes itself as: Monorepo for all of my projects. The licence is GPL-3.0.

When your agent uses it

  • Creates schemas
  • Handles form validation
  • Mentions z.object/z.string patterns
  • Needs runtime validation

Example prompts

  • “/zod-patterns”

Workflow steps

10 steps, taken from the first numbered list in SKILL.md.

  1. Use safeParse() - avoid throwing in production code
  2. Infer types - let Zod generate TypeScript types
  3. Compose schemas - use extend, pick, omit for reuse
  4. Prefer coercion over preprocess for type conversion
  5. Add custom messages - improve user-facing errors
  6. Use discriminated unions - for efficient tagged unions
  7. Brand sensitive types - prevent accidental ID swapping
  8. Validate at boundaries - API inputs, env vars, external data
  9. Use transforms sparingly - keep schemas focused on validation
  10. Test edge cases - empty strings, null, undefined

What it can do on your machine

Read from SKILL.md and the folder at commit 46ddf2f. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • bun

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Zod Patterns loads about 5k tokens when it runs. Until then it costs about 72 tokens; SKILL.md has 382 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~72
When it runs · the whole SKILL.md, loaded when a task matches
~5k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from shepherdjerred/monorepo at commit 46ddf2f, republished under its GPL-3.0 licence (© shepherdjerred). 382 words, ~5,034 tokens.

Download SKILL.mdSave it as .claude/skills/zod-patterns/SKILL.md (or your agent's skills folder).
name
zod-patterns
description
Zod schema validation, type-safe development, and strict TypeScript patterns. When user works with Zod, validates data, creates schemas, handles form validation, mentions z.object/z.string patterns, needs runtime validation, type-safe code, or strict TypeScript configuration.

Zod Patterns Agent

What's New in Zod 4 (2025)

  • Performance: z.array() 7.4x faster, z.object() 6.5x faster (compared to Zod v3)
  • Zod Mini: Tree-shakable functional API variant
  • Metadata API: Attach custom metadata to schemas
  • JSON Schema: Built-in JSON Schema generation
  • Locales: Built-in i18n support for error messages
  • z.looseObject(): Replaces .passthrough()
  • z.strictObject(): Replaces .strict()

Installation

bash
# Standard Zod v4 (recommended)
bun add zod

# Minimal bundle for tree-shaking (1.9KB gzipped)
bun add @zod/mini

Requires TypeScript 5.5+ with "strict": true in tsconfig.

Using @zod/mini
typescript
// Tree-shakable imports (only includes what you use)
import { z } from "@zod/mini";

// Same API as full Zod
const UserSchema = z.object({
  id: z.string(),
  email: z.string().email(),
});

// Results in significantly smaller bundles
// Full Zod: ~5KB | @zod/mini: ~1.9KB (tree-shaken)

For library authors targeting v4: import { z } from "zod/v4/core";

Basic Usage

Defining and Parsing
typescript
import { z } from "zod";

// Define a schema
const UserSchema = z.object({
  name: z.string(),
  email: z.string().email(),
  age: z.number().int().positive(),
});

// Parse data (throws on invalid)
const user = UserSchema.parse({
  name: "Alice",
  email: "alice@example.com",
  age: 25,
});

// Safe parse (returns result object)
const result = UserSchema.safeParse(data);
if (result.success) {
  console.log(result.data); // typed as User
} else {
  console.log(result.error.issues); // validation errors
}
Type Inference
typescript
// Infer TypeScript type from schema
type User = z.infer<typeof UserSchema>;
// { name: string; email: string; age: number }

// For schemas with transforms - input vs output types
type UserInput = z.input<typeof UserSchema>;
type UserOutput = z.output<typeof UserSchema>;

Primitive Types

Strings
typescript
z.string(); // any string
z.string().min(1); // non-empty
z.string().max(100); // max length
z.string().length(5); // exact length
z.string().email(); // email format
z.string().url(); // URL format
z.string().uuid(); // UUID format
z.string().cuid(); // CUID format
z.string().cuid2(); // CUID2 format
z.string().ulid(); // ULID format
z.string().regex(/^[a-z]+$/); // custom regex
z.string().includes("@"); // contains substring
z.string().startsWith("http"); // starts with
z.string().endsWith(".com"); // ends with
z.string().datetime(); // ISO datetime
z.string().date(); // ISO date
z.string().time(); // ISO time
z.string().ip(); // IP address
z.string().trim(); // trim whitespace (transform)
z.string().toLowerCase(); // lowercase (transform)
z.string().toUpperCase(); // uppercase (transform)
Numbers
typescript
z.number(); // any number
z.number().int(); // integer only
z.number().positive(); // > 0
z.number().nonnegative(); // >= 0
z.number().negative(); // < 0
z.number().nonpositive(); // <= 0
z.number().min(5); // >= 5
z.number().max(100); // <= 100
z.number().gt(5); // > 5
z.number().gte(5); // >= 5 (alias for min)
z.number().lt(100); // < 100
z.number().lte(100); // <= 100 (alias for max)
z.number().multipleOf(5); // divisible by 5
z.number().finite(); // not Infinity
z.number().safe(); // within safe integer range
Other Primitives
typescript
z.boolean(); // true or false
z.bigint(); // BigInt values
z.date(); // Date objects
z.undefined(); // undefined only
z.null(); // null only
z.void(); // undefined (for function returns)
z.any(); // bypass validation
z.unknown(); // any, but type-safe usage
z.never(); // always fails

Coercion

Automatically convert input types before validation:

typescript
// String coercion
z.coerce.string(); // String(input)
z.coerce.number(); // Number(input)
z.coerce.boolean(); // Boolean(input)
z.coerce.bigint(); // BigInt(input)
z.coerce.date(); // new Date(input)

// With validation
const ageSchema = z.coerce.number().int().positive();
ageSchema.parse("25"); // 25
ageSchema.parse("abc"); // throws - NaN is not positive

// Common pitfall: empty string becomes 0
z.coerce.number().parse(""); // 0 (might not be desired)

// Fix: preprocess to handle empty strings
const safeNumber = z.preprocess(
  (val) => (val === "" ? undefined : val),
  z.coerce.number(),
);

Objects

Basic Objects
typescript
const PersonSchema = z.object({
  name: z.string(),
  age: z.number(),
  email: z.string().email().optional(),
});

// By default, unknown keys are stripped
PersonSchema.parse({ name: "Bob", age: 30, extra: "ignored" });
// { name: "Bob", age: 30 }
Object Modes (Zod 4)
typescript
// Standard - strips unknown keys
z.object({ name: z.string() });

// Loose - passes through unknown keys
z.looseObject({ name: z.string() });

// Strict - rejects unknown keys
z.strictObject({ name: z.string() });
Object Manipulation
typescript
const UserSchema = z.object({
  id: z.string().uuid(),
  name: z.string(),
  email: z.string().email(),
  password: z.string(),
  createdAt: z.date(),
});

// Pick specific fields
const PublicUser = UserSchema.pick({ id: true, name: true, email: true });

// Omit sensitive fields
const SafeUser = UserSchema.omit({ password: true });

// Make all fields optional
const PartialUser = UserSchema.partial();

// Make specific fields optional
const UpdateUser = UserSchema.partial({ name: true, email: true });

// Make all fields required
const RequiredUser = UserSchema.required();

// Extend with additional fields
const AdminSchema = UserSchema.extend({
  role: z.literal("admin"),
  permissions: z.array(z.string()),
});

// Merge schemas (Zod 4 - use extend instead)
const Combined = BaseSchema.extend(ExtraSchema.shape);
Nested Objects
typescript
const AddressSchema = z.object({
  street: z.string(),
  city: z.string(),
  country: z.string(),
  zip: z.string().optional(),
});

const CompanySchema = z.object({
  name: z.string(),
  address: AddressSchema,
  employees: z.array(
    z.object({
      name: z.string(),
      department: z.string(),
    }),
  ),
});

Arrays and Collections

Arrays
typescript
z.array(z.string()); // string[]
z.array(z.string()).min(1); // at least 1 element
z.array(z.string()).max(10); // at most 10 elements
z.array(z.string()).length(5); // exactly 5 elements
z.array(z.string()).nonempty(); // same as .min(1)

// Access element schema
const arr = z.array(z.string());
arr.element; // z.string()
Tuples
typescript
// Fixed-length array with specific types
const PointSchema = z.tuple([z.number(), z.number()]);
type Point = z.infer<typeof PointSchema>; // [number, number]

// With rest elements
const ArgsSchema = z.tuple([z.string(), z.number()]).rest(z.boolean());
// [string, number, ...boolean[]]
Records and Maps
typescript
// Record<string, T>
z.record(z.string(), z.number()); // { [key: string]: number }
z.record(z.number()); // shorthand for string keys

// Map<K, V>
z.map(z.string(), z.number()); // Map<string, number>

// Set<T>
z.set(z.string()); // Set<string>
z.set(z.number()).min(1).max(10); // with size constraints

Unions and Enums

Unions
typescript
// Basic union
const StringOrNumber = z.union([z.string(), z.number()]);
type SN = z.infer<typeof StringOrNumber>; // string | number

// Shorthand
const StringOrNumber2 = z.string().or(z.number());
Discriminated Unions
typescript
// More efficient parsing with discriminator key
const ResultSchema = z.discriminatedUnion("status", [
  z.object({
    status: z.literal("success"),
    data: z.object({ id: z.string() }),
  }),
  z.object({
    status: z.literal("error"),
    message: z.string(),
  }),
]);

type Result = z.infer<typeof ResultSchema>;
// { status: "success"; data: { id: string } } | { status: "error"; message: string }

// TypeScript narrows based on discriminator
const result = ResultSchema.parse(data);
if (result.status === "success") {
  console.log(result.data.id); // typed correctly
}
Enums
typescript
// Zod enum (recommended)
const StatusSchema = z.enum(["pending", "active", "inactive"]);
type Status = z.infer<typeof StatusSchema>; // "pending" | "active" | "inactive"

// Access values
StatusSchema.options; // ["pending", "active", "inactive"]
StatusSchema.enum; // { pending: "pending", active: "active", ... }

// Extract or exclude values
StatusSchema.extract(["pending", "active"]); // only these
StatusSchema.exclude(["inactive"]); // all except these

// Native enum
enum NativeStatus {
  Pending,
  Active,
  Inactive,
}
const NativeStatusSchema = z.nativeEnum(NativeStatus);
Literals
typescript
z.literal("hello"); // exactly "hello"
z.literal(42); // exactly 42
z.literal(true); // exactly true
z.null(); // exactly null
z.undefined(); // exactly undefined

Optional, Nullable, Default

typescript
// Optional - allows undefined
z.string().optional(); // string | undefined

// Nullable - allows null
z.string().nullable(); // string | null

// Nullish - allows null or undefined
z.string().nullish(); // string | null | undefined

// Default values
z.string().default("N/A"); // static default
z.number().default(() => Math.random()); // dynamic default
z.date().default(() => new Date()); // current date

// Catch - use default on any parse error
z.number().catch(0); // returns 0 on error
z.string().catch((ctx) => `Error: ${ctx.error.message}`);

// Unwrap optional/nullable
const optStr = z.string().optional();
optStr.unwrap(); // z.string()

Refinements and Transforms

Refinements (Custom Validation)
typescript
// Basic refine
const PasswordSchema = z
  .string()
  .min(8, "Password must be at least 8 characters")
  .refine((val) => /[A-Z]/.test(val), "Password must contain uppercase letter")
  .refine((val) => /[0-9]/.test(val), "Password must contain number");

// With custom error path
const FormSchema = z
  .object({
    password: z.string(),
    confirmPassword: z.string(),
  })
  .refine((data) => data.password === data.confirmPassword, {
    message: "Passwords don't match",
    path: ["confirmPassword"], // error appears on this field
  });
SuperRefine (Multiple Issues)
typescript
const ComplexSchema = z.string().superRefine((val, ctx) => {
  if (val.length < 8) {
    ctx.addIssue({
      code: z.ZodIssueCode.too_small,
      minimum: 8,
      type: "string",
      inclusive: true,
      message: "Too short",
    });
  }
  if (!/[A-Z]/.test(val)) {
    ctx.addIssue({
      code: z.ZodIssueCode.custom,
      message: "Missing uppercase",
    });
  }
});
Transforms
typescript
// Transform output type
const TrimmedString = z.string().transform((val) => val.trim());

const NumberFromString = z
  .string()
  .transform((val) => parseInt(val, 10))
  .pipe(z.number().int());

const DateFromISO = z
  .string()
  .datetime()
  .transform((val) => new Date(val));

// Transform with validation
const PositiveFromString = z
  .string()
  .transform((val, ctx) => {
    const num = parseInt(val, 10);
    if (isNaN(num)) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message: "Not a number",
      });
      return z.NEVER;
    }
    return num;
  })
  .pipe(z.number().positive());
Preprocess
typescript
// Transform BEFORE parsing
const TrimmedEmail = z.preprocess(
  (val) => (typeof val === "string" ? val.trim().toLowerCase() : val),
  z.string().email(),
);

// Handle empty strings
const OptionalNumber = z.preprocess(
  (val) => (val === "" ? undefined : val),
  z.coerce.number().optional(),
);
Pipe (Chaining Schemas)
typescript
// Chain multiple schemas
const ParsedInt = z
  .string()
  .transform((val) => parseInt(val, 10))
  .pipe(z.number().int().positive());

// With intermediate validation
const EmailDomain = z
  .string()
  .email()
  .pipe(z.string().endsWith("@company.com"));

Error Handling

Custom Error Messages
typescript
// Per-validator messages
z.string().min(5, "Must be at least 5 characters");
z.string().min(5, { message: "Too short" });

// Schema-level errors
z.string("Expected a string");
z.string({
  error: (issue) =>
    issue.input === undefined ? "Field is required" : "Must be a string",
});
Parsing Errors
typescript
const result = UserSchema.safeParse(input);

if (!result.success) {
  // Formatted errors
  const formatted = result.error.format();
  // { name: { _errors: ["Required"] }, email: { _errors: ["Invalid email"] } }

  // Flattened errors
  const flat = result.error.flatten();
  // { formErrors: [], fieldErrors: { name: ["Required"], email: ["Invalid email"] } }

  // Raw issues
  result.error.issues.forEach((issue) => {
    console.log(issue.path, issue.message, issue.code);
  });
}
Error Maps
typescript
// Per-parse error customization
schema.parse(data, {
  error: (issue) => `Custom error: ${issue.code}`,
});

// Global configuration
z.config({
  customError: (issue) => {
    if (issue.code === "invalid_type") {
      return `Expected ${issue.expected}, got ${issue.received}`;
    }
    return issue.message;
  },
});

// Localization
import { en } from "zod/v4/locales/en";
z.config(en());

Advanced Patterns

Branded Types
typescript
const UserId = z.string().uuid().brand<"UserId">();
const PostId = z.string().uuid().brand<"PostId">();

type UserId = z.infer<typeof UserId>;
type PostId = z.infer<typeof PostId>;

function getUser(id: UserId) {
  /* ... */
}

const userId = UserId.parse("550e8400-e29b-41d4-a716-446655440000");
const postId = PostId.parse("550e8400-e29b-41d4-a716-446655440000");

getUser(userId); // OK
getUser(postId); // Type error!
Recursive Types
typescript
interface Category {
  name: string;
  subcategories: Category[];
}

const CategorySchema: z.ZodType<Category> = z.lazy(() =>
  z.object({
    name: z.string(),
    subcategories: z.array(CategorySchema),
  }),
);
JSON Type
typescript
// Generic JSON value
const JsonValue: z.ZodType<unknown> = z.lazy(() =>
  z.union([
    z.string(),
    z.number(),
    z.boolean(),
    z.null(),
    z.array(JsonValue),
    z.record(JsonValue),
  ]),
);
Function Schemas
typescript
const FnSchema = z.function().args(z.string(), z.number()).returns(z.boolean());

type Fn = z.infer<typeof FnSchema>;
// (args_0: string, args_1: number) => boolean

const validated = FnSchema.implement((name, age) => {
  return age > 18;
});
Async Validation
typescript
const UniqueEmailSchema = z
  .string()
  .email()
  .refine(async (email) => {
    const exists = await checkEmailExists(email);
    return !exists;
  }, "Email already taken");

// Must use async parse
const result = await UniqueEmailSchema.safeParseAsync("test@example.com");

Integration Patterns

Form Validation
typescript
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";

const FormSchema = z.object({
  email: z.string().email("Invalid email"),
  password: z.string().min(8, "At least 8 characters"),
});

function MyForm() {
  const { register, handleSubmit, formState: { errors } } = useForm({
    resolver: zodResolver(FormSchema),
  });

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("email")} />
      {errors.email && <span>{errors.email.message}</span>}
      {/* ... */}
    </form>
  );
}
API Validation
typescript
// Hono example
import { zValidator } from "@hono/zod-validator";

const CreateUserSchema = z.object({
  name: z.string().min(1),
  email: z.string().email(),
});

app.post("/users", zValidator("json", CreateUserSchema), async (c) => {
  const data = c.req.valid("json");
  // data is fully typed
});
Environment Variables
typescript
const EnvSchema = z.object({
  DATABASE_URL: z.string().url(),
  PORT: z.coerce.number().default(3000),
  NODE_ENV: z
    .enum(["development", "production", "test"])
    .default("development"),
  API_KEY: z.string().min(1),
});

export const env = EnvSchema.parse(process.env);

Replacing Common Type Checks with Zod

Prefer Zod validation over typeof, instanceof, or type guard functions.

typeof / instanceof / Number checks → Zod
typescript
// ❌ Avoid typeof operator
if (typeof value === "string") {
  return value.toUpperCase();
}

// ✅ Prefer Zod validation
const result = z.string().safeParse(value);
if (result.success) {
  return result.data.toUpperCase();
}

// ❌ Avoid instanceof
if (err instanceof Error) {
  console.log(err.message);
}

// ✅ Prefer Zod
const result = z.instanceof(Error).safeParse(err);
if (result.success) {
  console.log(result.data.message);
}

// ❌ Avoid Number.isInteger
if (Number.isInteger(value)) {
  return value * 2;
}

// ✅ Prefer Zod
const result = z.number().int().safeParse(value);
if (result.success) {
  return result.data * 2;
}
Type predicates → Zod
typescript
// ❌ Avoid type guard functions
function isUser(value: unknown): value is User {
  return typeof value === "object" && value !== null && "email" in value;
}

// ✅ Prefer Zod schema validation
const UserSchema = z.object({
  email: z.string().email(),
  name: z.string(),
});

const result = UserSchema.safeParse(value);
if (result.success) {
  const user = result.data; // Type-safe!
}

Type Assertions Rules

Only as unknown and as const are allowed — all other as casts are banned.

typescript
// ❌ Never do this - bypasses type safety
const user = data as User;
const id = value as string;

// ✅ Cast to unknown first, then validate
const data = response as unknown;
const result = UserSchema.safeParse(data);
if (result.success) {
  const user = result.data;
}

// ✅ Use 'as const' for literal types
const STATUSES = ["pending", "approved", "rejected"] as const;
type Status = (typeof STATUSES)[number];

Why no type assertions? They bypass TypeScript's type checking, don't perform runtime validation, can cause runtime crashes, and hide bugs instead of catching them. Zod gives you both compile-time AND runtime safety.

Show full SKILL.md (144 more words)Show less

Strict TypeScript Configuration

tsconfig.json Best Practices
json
{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noPropertyAccessFromIndexSignature": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitOverride": true,
    "noFallthroughCasesInSwitch": true,
    "forceConsistentCasingInFileNames": true
  }
}
Use 'type' Instead of 'interface'
typescript
// ✅ Prefer type
type User = {
  id: string;
  email: string;
};

type Admin = User & {
  permissions: string[];
};

// ❌ Avoid interface
interface User {
  id: string;
  email: string;
}

Why? Types are more flexible (unions, intersections) and consistent with Zod's inferred types.

Best Practices Summary

  1. Use safeParse() - avoid throwing in production code
  2. Infer types - let Zod generate TypeScript types
  3. Compose schemas - use extend, pick, omit for reuse
  4. Prefer coercion over preprocess for type conversion
  5. Add custom messages - improve user-facing errors
  6. Use discriminated unions - for efficient tagged unions
  7. Brand sensitive types - prevent accidental ID swapping
  8. Validate at boundaries - API inputs, env vars, external data
  9. Use transforms sparingly - keep schemas focused on validation
  10. Test edge cases - empty strings, null, undefined

When to Ask for Help

  • Complex recursive schema patterns
  • Performance optimization for high-throughput validation
  • Integration with specific ORMs or frameworks
  • Migration from other validation libraries
  • Custom error formatting requirements
  • Schema generation from external sources

© shepherdjerred, GPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in packages/dotfiles/dot_agents/skills/zod-patterns of shepherdjerred/monorepo.

Open the folder on GitHubat commit 46ddf2f

Compare with similar skills

Zod Patterns next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Zod Patterns compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Zod Patterns this skillshepherdjerred/monorepo112—~5kAutomated safety check: PassGPL-3.0
Mastra Honojwynia/agent-skills165—~2.9kAutomated safety check: PassMIT
Desloppifydatabuddy-analytics/Databuddy1.2k—~2.7kAutomated safety check: PassAGPL-3.0
Zod Validation Expertdavila7/claude-code-templates32k3 repos~2.4kAutomated safety check: PassMIT
Shadcn UIjh941213/my-cc-harness1264 repos~9.7kAutomated safety check: NotesMIT
Typescript Patternssoftspark/ai-toolkit179—~1.6kAutomated safety check: PassApache-2.0

Similar skills

  • Mastra Hono

    jwynia/agent-skills

    Develop AI agents, tools, and workflows with Mastra v1 Beta and Hono servers.

    165 GitHub stars~2.9k tokensUpdated 7 mo ago
    Frontend & DesignAuto-check passed
  • Desloppify

    databuddy-analytics/Databuddy

    Reduce codebase slop by deleting code, flattening abstractions, and replacing custom helpers/types/assertions with native SDK/npm helpers or straightforward schemas (for example Zod).

    1.2k GitHub stars~2.7k tokensUpdated today
    Frontend & DesignAuto-check passed
  • Zod Validation Expert

    davila7/claude-code-templates

    Expert in Zod — TypeScript-first schema validation. An agent skill from davila7/claude-code-templates.

    32k GitHub starsUsed in 3 repos~2.4k tokens
    Frontend & DesignAuto-check passed
  • Shadcn UI

    jh941213/my-cc-harness

    Complete shadcn/ui component library guide including installation, configuration, and implementation of accessible React components.

    126 GitHub starsUsed in 4 repos~9.7k tokens
    Frontend & DesignAuto-check: notes
  • Typescript Patterns

    softspark/ai-toolkit

    TypeScript types: generics, discriminated unions, Zod, satisfies, branded types.

    179 GitHub stars~1.6k tokensUpdated yesterday
    Frontend & DesignAuto-check passed
  • Typescript Core

    bobmatnyc/claude-mpm

    Advanced TypeScript patterns and best practices for 2025. An agent skill from bobmatnyc/claude-mpm.

    155 GitHub stars~2.2k tokensUpdated 1 mo ago
    Frontend & DesignAuto-check passed

More from shepherdjerred/monorepo

All 63 skills in this repo
  • Bun Runtime Best Practices

    shepherdjerred/monorepo

    Bun runtime APIs and current operational patterns for files, processes, modules, networking, databases, tests, and deployment.

    112 GitHub stars~2k tokensUpdated today
    Auto-check passed
  • Bun Test Patterns

    shepherdjerred/monorepo

    Current Bun test runner guidance for discovery, isolation, parallelism, sharding, changed tests, mocks, timers, snapshots, coverage, DOM Testing Library, and integration teardown.

    112 GitHub stars~2k tokensUpdated today
    Auto-check passed
  • Bun Workspaces

    shepherdjerred/monorepo

    Current Bun workspace guidance for isolated and hoisted linkers, catalogs, filters, scripts, dependency classes, lockfiles, lifecycle trust, caches, publishing, TypeScript package exports, and…

    112 GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Deep Research

    shepherdjerred/monorepo

    This skill should be used when the user asks to "deep research", "research this topic", "investigate thoroughly", "do a deep dive on", "comprehensive research on", "find everything about", "survey…

    112 GitHub stars~4.7k tokensUpdated today
    Auto-check: notes
  • Figma Use

    shepherdjerred/monorepo

    This skill should be used when the user asks to "create a Figma design", "design in Figma", "make a Figma mockup", "create an app icon", "design UI", "render JSX to Figma", "export from Figma"…

    112 GitHub stars~946 tokensUpdated today
    Auto-check passed
  • Fish Helper

    shepherdjerred/monorepo

    Current Fish shell scripting, functions, abbreviations, completions, variables, events, configuration, plugins, testing, and safety guidance.

    112 GitHub stars~2k tokensUpdated today
    Auto-check passed

Works with

Questions about Zod Patterns

What does Zod Patterns do?

Zod schema validation, type-safe development, and strict TypeScript patterns. Zod Patterns is an agent skill from shepherdjerred/monorepo. Zod schema validation, type-safe development, and strict TypeScript patterns.

When should I use Zod Patterns?

Zod Patterns fits situations like: creates schemas; handles form validation; mentions z.object/z.string patterns; needs runtime validation.

How do I install Zod Patterns in Claude Code?

Run `npx skills add shepherdjerred/monorepo --skill zod-patterns -a claude-code`. Or copy the skill folder (packages/dotfiles/dot_agents/skills/zod-patterns in shepherdjerred/monorepo) into .claude/skills/zod-patterns in your project. Claude Code loads it when a task matches its description.

How do I install Zod Patterns in Codex?

Run `npx skills add shepherdjerred/monorepo --skill zod-patterns -a codex`. Or copy the skill folder (packages/dotfiles/dot_agents/skills/zod-patterns in shepherdjerred/monorepo) into .agents/skills/zod-patterns in your project. Codex loads it when a task matches its description.

Can I use Zod Patterns in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add shepherdjerred/monorepo --skill zod-patterns -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/zod-patterns, .gemini/skills/zod-patterns, .github/skills/zod-patterns and .opencode/skills/zod-patterns in your project.

What does Zod Patterns need to run?

Going by SKILL.md and its folder, Zod Patterns needs the command-line tools its instructions call (bun) and credentials named API_KEY.

Does Zod Patterns access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Zod Patterns safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Zod Patterns use?

Zod Patterns is published under the GPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Zod Patterns use?

About 5k tokens (SKILL.md is roughly 20k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Zod Patterns?

Skills that share tags, products or a category with Zod Patterns: Mastra Hono (jwynia/agent-skills, 165 stars), Desloppify (databuddy-analytics/Databuddy, 1.2k stars), Zod Validation Expert (davila7/claude-code-templates, 32k stars) and Shadcn UI (jh941213/my-cc-harness, 126 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Zod Patterns?

shepherdjerred (a GitHub user) maintains it in shepherdjerred/monorepo, which has 112 GitHub stars. The repository holds 63 skills in this directory. The repository was last updated on October 7, 2026.

Source: shepherdjerred/monorepo on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.