Mastra Hono
jwynia/agent-skills
Develop AI agents, tools, and workflows with Mastra v1 Beta and Hono servers.
TypeScript-first schema validation and type inference. An agent skill from secondsky/claude-skills.
$ npx skills add secondsky/claude-skills --skill zod -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install secondsky/claude-skills zod --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/secondsky/claude-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/zod/skills/zod .claude/skills/zod && rm -rf skills-srcUse ~/.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/
Install the "zod" agent skill from https://github.com/secondsky/claude-skills/tree/main/plugins/zod/skills/zod into .claude/skills/zod/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "zod", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/secondsky/claude-skills/tree/main/plugins/zod/skills/zodType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add secondsky/claude-skills --skill zod -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install secondsky/claude-skills zod --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/secondsky/claude-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/plugins/zod/skills/zod .agents/skills/zod && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "zod" agent skill from https://github.com/secondsky/claude-skills/tree/main/plugins/zod/skills/zod into .agents/skills/zod/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "zod", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add secondsky/claude-skills --skill zod -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install secondsky/claude-skills zod --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/secondsky/claude-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/plugins/zod/skills/zod .cursor/skills/zod && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "zod" agent skill from https://github.com/secondsky/claude-skills/tree/main/plugins/zod/skills/zod into .cursor/skills/zod/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "zod", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/secondsky/claude-skills.git --path plugins/zod/skills/zod--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add secondsky/claude-skills --skill zod -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install secondsky/claude-skills zod --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/secondsky/claude-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/plugins/zod/skills/zod .gemini/skills/zod && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "zod" agent skill from https://github.com/secondsky/claude-skills/tree/main/plugins/zod/skills/zod into .gemini/skills/zod/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "zod", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install secondsky/claude-skills zodInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add secondsky/claude-skills --skill zod -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/secondsky/claude-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/plugins/zod/skills/zod .github/skills/zod && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "zod" agent skill from https://github.com/secondsky/claude-skills/tree/main/plugins/zod/skills/zod into .github/skills/zod/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "zod", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add secondsky/claude-skills --skill zod -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install secondsky/claude-skills zod --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/secondsky/claude-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/plugins/zod/skills/zod .opencode/skills/zod && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "zod" agent skill from https://github.com/secondsky/claude-skills/tree/main/plugins/zod/skills/zod into .opencode/skills/zod/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "zod", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
zodTypeScript-first schema validation and type inference. An agent skill from secondsky/claude-skills.
Zod is an agent skill from secondsky/claude-skills. TypeScript-first schema validation and type inference. Use for validating API requests/responses, form data, env vars, configs, defining type-safe schemas with runtime validation, transforming data, generating JSON Schema for OpenAPI/AI, or encountering missing validation errors, type inference issues, validation error handling problems. Zero dependencies, compact core (~5kb gzipped; zod/mini ~1.9kb).
Its SKILL.md is about 7k tokens, which your agent loads only when the skill is triggered. The skill folder holds 13 other files, including reference files (for example `references/advanced-patterns.md`, `references/best-practices.md` and `references/common-patterns.ts`).
It sits in Frontend & Design, covering Forms and validation. It works with Zod, TypeScript and OpenAPI. The repository describes itself as: Production-ready skills for Claude Code CLI - Cloudflare, React, Tailwind v4, and AI integrations. The licence is MIT.
6 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 8837836. It shows what the files ask for, not the result of running them.
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.
Ships script files (TypeScript and JavaScript), which the agent can run.
Shell commands in SKILL.md call:
bunnpmpnpmyarnFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
zod.devgithub.comzod-playground.vercel.apptrpc.ioFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
API_KEYFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Zod loads about 7k tokens when it runs, and up to ~35k if it reads all its reference files. Until then it costs about 102 tokens; SKILL.md has 1,190 words of instructions outside code blocks.
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.
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.
The full file from secondsky/claude-skills at commit 8837836, republished under its MIT licence (© secondsky). 1,190 words, ~6,994 tokens.
.claude/skills/zod/SKILL.md (or your agent's skills folder). This skill also uses 12 other files; get the full folder from GitHub.Zod is a TypeScript-first validation library that enables developers to define schemas for validating data at runtime while automatically inferring static TypeScript types. With zero dependencies and a compact core (~5kb gzipped; ~1.9kb for zod/mini), Zod provides immutable, composable validation with comprehensive error handling.
bun add zod
# or
npm install zod
# or
pnpm add zod
# or
yarn add zodRequirements:
"strict": true in tsconfig.jsonz.codec() requires 4.1+)Important: This skill documents Zod 4.x features. The following APIs require Zod 4 and are NOT available in Zod 3.x:
z.codec() - Bidirectional transformationsz.iso.date(), z.iso.time(), z.iso.datetime(), z.iso.duration() - ISO format validatorsz.toJSONSchema() - JSON Schema generationz.treeifyError(), z.prettifyError(), z.flattenError() - New error formatting helpers.meta() - Enhanced metadata (Zod 3.x only has .describe())error parameter - Replaces message, invalid_type_error, required_error, errorMap.check() - Low-level multi-issue validation (composes check factories like z.minLength(3))z.file(), z.json(), z.stringbool(), z.xor(), z.templateLiteral() - New schema typesz.exactOptional(), .prefault(), .safeExtend(), z.fromJSONSchema() - New utilitiesFor Zod 3.x compatibility or migration guidance, see https://zod.dev
Import paths (all ship in the zod package):
import { z } from "zod" — standard (v4 since 4.0)import { z } from "zod/v4" — pin for libraries supporting both v3 (3.25+) and v4 usersimport { z } from "zod/mini" — functional, tree-shakable API (~1.9kb; checks via .check(z.minLength(3)))import * as core from "zod/v4/core" — low-level $-prefixed internals for library authorsLoad references/migration-guide.md for complete v3 to v4 migration documentation.
Zod v4 introduces breaking changes for better performance:
error parameter (replaces message, invalid_type_error, required_error)Infinity and unsafe integersz.email() instead of z.string().email(); the method forms still work but are deprecated).extend() (not .merge()), z.treeifyError() (not error.format()).implement() method→ Load references/migration-guide.md for: Complete breaking changes, migration checklist, gradual migration strategy, rollback instructions
import { z } from "zod";
// Define schema
const UserSchema = z.object({
username: z.string(),
age: z.number().int().positive(),
email: z.email(),
});
// Infer TypeScript type
type User = z.infer<typeof UserSchema>;
// Validate data (throws on error)
const user = UserSchema.parse(data);
// Validate data (returns result object)
const result = UserSchema.safeParse(data);
if (result.success) {
console.log(result.data); // Typed!
} else {
console.error(result.error); // ZodError
}Use the appropriate parsing method based on error handling needs:
.parse(data) - Throws ZodError on invalid input; returns strongly-typed data on success.safeParse(data) - Returns { success: true, data } or { success: false, error } (no exceptions).parseAsync(data) - For schemas with async refinements/transforms.safeParseAsync(data) - Async version that doesn't throwBest Practice: Use .safeParse() to avoid try-catch blocks and leverage discriminated unions.
z.string() // Basic string
z.string().min(5) // Minimum length
z.string().max(100) // Maximum length
z.string().length(10) // Exact length
z.email() // Email validation (top-level in v4)
z.url() // URL validation (top-level in v4)
z.uuid() // UUID (RFC 9562; use z.guid() for permissive)
z.uuidv4() // Version-specific UUIDs (also z.uuidv7)
z.httpUrl() // http/https URLs only (rejects ftp:// etc.)
z.e164() // Phone numbers (E.164 format)
z.string().regex(/^\d+$/) // Custom pattern
z.string().startsWith("pre") // Prefix check
z.string().endsWith("suf") // Suffix check
z.string().trim() // Auto-trim whitespace
z.string().toLowerCase() // Auto-lowercase
z.string().toUpperCase() // Auto-uppercase
// ISO formats (Zod 4+)
z.iso.date() // YYYY-MM-DD
z.iso.time() // HH:MM:SS
z.iso.datetime() // ISO 8601 datetime
z.iso.duration() // ISO 8601 duration
// Network formats
z.ipv4() // IPv4 address
z.ipv6() // IPv6 address
z.cidrv4() // IPv4 CIDR notation
z.cidrv6() // IPv6 CIDR notation
// Other formats
z.jwt() // JWT token
z.nanoid() // Nanoid
z.cuid() // CUID
z.cuid2() // CUID2
z.ulid() // ULID
z.base64() // Base64 encoded
z.hex() // Hexadecimal
z.hash("sha256") // Hash of algorithm-specific length
z.guid() // Permissive UUID/GUID (non-RFC)
z.hostname() // Hostname
z.mac() // MAC address
z.uuid({ version: "v4" }) // UUID with version constraint
z.email({ pattern: z.regexes.email }) // Email with explicit patternz.number() // Basic 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(0) // Minimum value
z.number().max(100) // Maximum value
z.number().gt(0) // Greater than
z.number().gte(0) // Greater than or equal
z.number().lt(100) // Less than
z.number().lte(100) // Less than or equal
z.number().multipleOf(5) // Must be multiple of 5
z.int() // Shorthand for z.number().int()
z.int32() // 32-bit integer (also z.uint32, z.int64, z.uint64)
z.float32() // 32-bit float (also z.float64)
z.nan() // NaN valuez.coerce.string() // Convert to string
z.coerce.number() // Convert to number
z.coerce.boolean() // Convert to boolean
z.coerce.bigint() // Convert to bigint
z.coerce.date() // Convert to Date
// Example: Parse query parameters
const QuerySchema = z.object({
page: z.coerce.number().int().positive(),
limit: z.coerce.number().int().max(100).default(10),
});
// "?page=5&limit=20" -> { page: 5, limit: 20 }z.boolean() // Boolean
z.date() // Date object
z.date().min(new Date("2020-01-01"))
z.date().max(new Date("2030-12-31"))
z.bigint() // BigInt
z.symbol() // Symbol
z.null() // Null
z.undefined() // Undefined
z.void() // Void (undefined)
// File validation (v4) — sizes are bytes
z.file().min(1).max(5 * 1024 * 1024).mime(["image/png"])
// JSON-representable values (v4) — validates the VALUE is JSON-serializable
// (recursive union of string | number | boolean | null | array | record)
z.json()
// Env-style boolean coercion: "true"/"yes"/"1" → true (v4)
z.stringbool({ truthy: ["true", "yes", "1"], falsy: ["false", "no", "0"] })const PersonSchema = z.object({
name: z.string(),
age: z.number(),
address: z.object({
street: z.string(),
city: z.string(),
country: z.string(),
}),
});
type Person = z.infer<typeof PersonSchema>;
// Object methods
PersonSchema.shape // Access shape
PersonSchema.keyof() // Get union of keys
PersonSchema.extend({ role: z.string() }) // Add fields
PersonSchema.safeExtend({ role: z.string() }) // Type-safe extend (inherits refinements)
PersonSchema.pick({ name: true }) // Pick specific fields
PersonSchema.omit({ age: true }) // Omit fields
PersonSchema.partial() // Make all fields optional
PersonSchema.partial({ age: true }) // Make specific fields optional
PersonSchema.required() // Make all fields required
// NOTE: .deepPartial() was REMOVED in v4 — build recursive partials manually
// (top-level z.deepPartial() landed post-4.4.3 and is not yet stable)
// Strict vs loose objects
z.strictObject({ ... }) // No extra keys allowed (throws)
z.object({ ... }) // Strips extra keys (default)
z.looseObject({ ... }) // Allows extra keys
z.object({ ... }).catchall(z.number()) // Validate (and keep) unknown keysz.array(z.string()) // String array
z.array(z.number()).min(1) // At least 1 element
z.array(z.number()).max(10) // At most 10 elements
z.array(z.number()).length(5) // Exactly 5 elements
z.array(z.number()).nonempty() // At least 1 element
// Nested arrays
z.array(z.array(z.number())) // number[][]z.tuple([z.string(), z.number()]) // [string, number]
z.tuple([z.string(), z.number()]).rest(z.boolean()) // [string, number, ...boolean[]]// Enum
const RoleEnum = z.enum(["admin", "user", "guest"]);
type Role = z.infer<typeof RoleEnum>; // "admin" | "user" | "guest"
// Literal values
z.literal("exact_value")
z.literal(42)
z.literal(true)
// Native TypeScript enum
enum Fruits {
Apple,
Banana,
}
z.nativeEnum(Fruits)
// Enum methods
RoleEnum.enum.admin // "admin"
RoleEnum.exclude(["guest"]) // Exclude values
RoleEnum.extract(["admin", "user"]) // Include only// Basic union
z.union([z.string(), z.number()])
// Discriminated union (better performance & type inference)
const ResponseSchema = z.discriminatedUnion("status", [
z.object({ status: z.literal("success"), data: z.any() }),
z.object({ status: z.literal("error"), message: z.string() }),
]);
type Response = z.infer<typeof ResponseSchema>;
// { status: "success", data: any } | { status: "error", message: string }
// Exclusive union (v4): must match exactly ONE branch
z.xor([z.object({ a: z.string() }), z.object({ b: z.number() })])const BaseSchema = z.object({ id: z.string() });
const ExtendedSchema = z.object({ name: z.string() });
const Combined = z.intersection(BaseSchema, ExtendedSchema);
// Equivalent to: z.object({ id: z.string(), name: z.string() })// Record: object with typed keys and values (BOTH args required in v4)
z.record(z.string(), z.number()) // { [key: string]: number }
z.record(z.enum(["a", "b"]), z.string()) // Exhaustive: both keys REQUIRED
// Partial record (enum keys optional)
z.partialRecord(z.enum(["a", "b"]), z.string())
// Map
z.map(z.string(), z.number()) // Map<string, number>
z.set(z.string()) // Set<string>Load references/advanced-patterns.md for complete advanced validation and transformation patterns.
Refinements (custom validation):
z.string().refine((val) => val.length >= 8, "Too short");
z.object({ password, confirmPassword }).superRefine((data, ctx) => { /* ... */ });Transformations (modify data):
z.string().transform((val) => val.trim());
z.string().pipe(z.coerce.number());
z.preprocess((v) => (typeof v === "string" ? v.trim() : v), z.string()); // Transform BEFORE parsing
z.custom<string>((v) => typeof v === "string", { error: "Not a string" }); // Fully custom schemaMulti-issue validation (.check(), v4):
z.string().check(z.minLength(3), z.startsWith("a")); // Compose check factories
z.string().check((payload) => {
if (payload.value === "forbidden") {
payload.issues.push({ code: "custom", message: "Not allowed", input: payload.value });
}
});Template literals (v4):
const UserRole = z.templateLiteral(["role-", z.string()]); // "role-admin", "role-editor", ...Codecs (bidirectional transforms - NEW in v4.1):
const DateCodec = z.codec(
z.iso.datetime(),
z.date(),
{
decode: (str) => new Date(str),
encode: (date) => date.toISOString(),
}
);Recursive Types:
const CategorySchema: z.ZodType<Category> = z.lazy(() =>
z.object({ name: z.string(), subcategories: z.array(CategorySchema) })
);Optional/Nullable:
z.string().optional() // string | undefined
z.string().nullable() // string | null
z.string().default("default") // Provides default if undefinedReadonly & Brand:
z.object({ ... }).readonly() // Readonly properties
z.string().brand<"UserId">() // Nominal typing→ Load references/advanced-patterns.md for: Complete refinement patterns, async validation, codec examples, composable schemas, conditional validation, performance optimization
Load references/error-handling.md for complete error formatting and customization guide.
Error Formatting Methods:
// For forms
const { fieldErrors } = z.flattenError(error);
// For nested data
const tree = z.treeifyError(error);
const nameError = tree.properties?.user?.properties?.name?.errors?.[0];
// For debugging
console.log(z.prettifyError(error));Custom Error Messages (three levels):
// 1. Schema-level (highest priority)
z.string({ error: "Custom message" });
z.string().min(5, "Too short");
// 2. Per-parse level
schema.parse(data, { error: (issue) => "..." });
// 3. Global level
z.config({ customError: (issue) => "..." });Localization (40+ languages):
z.config(z.locales.es()); // Spanish
z.config(z.locales.fr()); // French→ Load references/error-handling.md for: Complete error formatting examples, custom error patterns, localization setup, error code reference
Load references/type-inference.md for complete type inference and metadata documentation.
Basic Type Inference:
const UserSchema = z.object({ name: z.string() });
type User = z.infer<typeof UserSchema>; // { name: string }Input vs Output (for transforms):
const TransformSchema = z.string().transform((s) => s.length);
type Input = z.input<typeof TransformSchema>; // string
type Output = z.output<typeof TransformSchema>; // numberJSON Schema Conversion:
const jsonSchema = z.toJSONSchema(UserSchema, {
target: "openapi-3.0",
// .meta() data from the global registry is included by default
});Metadata:
// Add metadata
const EmailSchema = z.email().meta({
title: "Email Address",
description: "User's email address",
});
// Create custom registry
const formRegistry = z.registry<FormFieldMeta>();→ Load references/type-inference.md for: Complete type inference patterns, JSON Schema options, metadata system, custom registries, brand types
Validate function inputs and outputs with the v4 factory signature:
const AddFunction = z.function({
input: [z.number(), z.number()], // Arguments
output: z.number(), // Return type
});
// Implement typed function
const add = AddFunction.implement((a, b) => {
return a + b; // Type-checked!
});
// Async functions
const FetchFunction = z.function({
input: [z.string()],
output: z.object({ data: z.any() }),
});
const fetchJson = FetchFunction.implementAsync(async (url) => {
const response = await fetch(url);
return response.json();
});Note: the v3 chaining style (z.function().args(...).returns(...)) was removed in v4.
const EnvSchema = z.object({
NODE_ENV: z.enum(["development", "production", "test"]),
DATABASE_URL: z.url(),
PORT: z.coerce.number().int().positive().default(3000),
API_KEY: z.string().min(32),
});
// Validate on startup
const env = EnvSchema.parse(process.env);
// Now use typed env
console.log(env.PORT); // numberconst CreateUserRequest = z.object({
username: z.string().min(3).max(20),
email: z.email(),
password: z.string().min(8),
age: z.number().int().positive().optional(),
});
// Express example
app.post("/users", async (req, res) => {
const result = CreateUserRequest.safeParse(req.body);
if (!result.success) {
return res.status(400).json({
errors: z.flattenError(result.error).fieldErrors,
});
}
const user = await createUser(result.data);
res.json(user);
});const FormSchema = z.object({
firstName: z.string().min(1, "First name required"),
lastName: z.string().min(1, "Last name required"),
email: z.email({ error: "Invalid email" }),
age: z.coerce.number().int().min(18, "Must be 18+"),
agreeToTerms: z.literal(true, {
error: () => "Must accept terms",
}),
});
type FormData = z.infer<typeof FormSchema>;const UserSchema = z.object({
id: z.string(),
name: z.string(),
email: z.email(),
});
// For PATCH requests: make everything optional except id
const UpdateUserSchema = UserSchema.partial().required({ id: true });
type UpdateUser = z.infer<typeof UpdateUserSchema>;
// { id: string; name?: string; email?: string }// Base schemas
const TimestampSchema = z.object({
createdAt: z.date(),
updatedAt: z.date(),
});
const AuthorSchema = z.object({
authorId: z.string(),
authorName: z.string(),
});
// Compose into larger schemas (.merge() is deprecated — use .extend with .shape)
const PostSchema = z.object({
id: z.string(),
title: z.string(),
content: z.string(),
}).extend(TimestampSchema.shape).extend(AuthorSchema.shape);Load references/ecosystem-integrations.md for complete framework and tooling integration guide.
ESLint Plugins:
eslint-plugin-zod-x - Enforces best practiceseslint-plugin-import-zod - Enforces import styleFramework Integrations:
react-hook-form-zod skill)Code Generation:
→ Load references/ecosystem-integrations.md for: Setup instructions, integration examples, Hono middleware, Drizzle ORM patterns
Load references/troubleshooting.md for complete troubleshooting guide, performance tips, and best practices.
Common Issues:
tsconfig.jsonz.lazy() for code splittingz.lazy()z.discriminatedUnion().refine() for validation, .transform() for modificationPerformance Tips:
.discriminatedUnion() (5-10x faster than .union()).safeParse() (avoids try-catch overhead)Best Practices:
z.infer).meta()→ Load references/troubleshooting.md for: Detailed solutions, performance optimization, best practices, testing patterns
// Primitives
z.string(), z.number(), z.boolean(), z.date(), z.bigint()
// Collections
z.array(), z.tuple(), z.object(), z.record(), z.map(), z.set()
// Special types
z.enum(), z.union(), z.discriminatedUnion(), z.intersection()
z.literal(), z.any(), z.unknown(), z.never()
// Modifiers
.optional(), .nullable(), .nullish(), .default(), .prefault()
.catch(), .readonly(), .brand(), .exactOptional()
// Validation
.min(), .max(), .length(), .regex()
.refine(), .superRefine(), .check(z.minLength(3))
// Top-level formats (v4)
z.email(), z.uuid(), z.url(), z.iso.datetime(), z.file(), z.json()
// Transformation
.transform(), .pipe(), .codec(), z.preprocess(), z.custom()
// Composition helpers
z.strictObject(), z.looseObject(), z.xor(), z.templateLiteral()
// Parsing
.parse(), .safeParse(), .parseAsync(), .safeParseAsync()
// Type inference
z.infer<typeof Schema>, z.input<typeof Schema>, z.output<typeof Schema>
// Error handling
z.flattenError(), z.treeifyError(), z.prettifyError()
// JSON Schema
z.toJSONSchema(schema, options)
// Metadata
.meta(), .describe()
// Object methods
.extend(), .safeExtend(), .pick(), .omit(), .partial(), .required()
.catchall(), .keyof() // .merge() is deprecated — use .extend(other.shape)Load references/migration-guide.md when:
.merge(), error.format(), etc.)Infinity or unsafe integersLoad references/error-handling.md when:
z.flattenError(), z.treeifyError(), or z.prettifyError()Load references/advanced-patterns.md when:
.refine(), .transform(), or .codec()Load references/type-inference.md when:
z.infer, z.input, z.outputLoad references/ecosystem-integrations.md when:
Load references/troubleshooting.md when:
.refine() and .transform()Load references/best-practices.md when:
any vs unknownJSON.parse, double validation)Production Notes:
What's New in 2.1.0:
references/best-practices.md rulebook (Incorrect/Correct/When-NOT format with impact ratings)zod/mini, .check(), catchall, z.preprocess, z.custom, z.templateLiteral, z.file/z.json/z.stringbool/z.xor, z.exactOptional, .safeExtend, z.fromJSONSchema, expanded format validatorsz.string().uuid() → z.uuid(), v3 .merge()/z.function() chains, .deepPartial() (removed in v4), single-arg z.record, toJSONSchema metadata optionWhat's New in 2.0.0:
© secondsky, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 12 other files (references) in plugins/zod/skills/zod of secondsky/claude-skills.
Open the folder on GitHubat commit 8837836
Zod 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.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Zod this skillsecondsky/claude-skills | 227 | — | ~7k | Automated safety check: Pass | MIT | |
| Mastra Honojwynia/agent-skills | 165 | — | ~2.9k | Automated safety check: Pass | MIT | |
| Desloppifydatabuddy-analytics/Databuddy | 1.2k | — | ~2.7k | Automated safety check: Pass | AGPL-3.0 | |
| Type Safetyidavidov13/agentic-playwright | 223 | — | ~3.5k | Automated safety check: Pass | MIT | |
| Zod Validation Expertdavila7/claude-code-templates | 32k | 3 repos | ~2.4k | Automated safety check: Pass | MIT | |
| Shadcn UIjh941213/my-cc-harness | 126 | 4 repos | ~9.7k | Automated safety check: Notes | MIT |
jwynia/agent-skills
Develop AI agents, tools, and workflows with Mastra v1 Beta and Hono servers.
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).
idavidov13/agentic-playwright
TypeScript type safety conventions for the Playwright scaffold — the "no any" rule, Zod 4 schema patterns (z.strictObject, top-level validators like z.uuid / z.email / z.url / z.int / z.enum)…
davila7/claude-code-templates
Expert in Zod — TypeScript-first schema validation. An agent skill from davila7/claude-code-templates.
jh941213/my-cc-harness
Complete shadcn/ui component library guide including installation, configuration, and implementation of accessible React components.
softspark/ai-toolkit
TypeScript types: generics, discriminated unions, Zod, satisfies, branded types.
secondsky/claude-skills
TanStack AI (alpha) provider-agnostic type-safe chat with streaming for OpenAI, Anthropic, Gemini, Ollama.
secondsky/claude-skills
AutoAnimate (@formkit/auto-animate) zero-config animations for React.
secondsky/claude-skills
MUI Base UI unstyled React components with Floating UI. An agent skill from secondsky/claude-skills.
secondsky/claude-skills
This skill should be used when the user asks to "upload images to Cloudflare", "implement direct creator upload", "configure image transformations", "optimize WebP/AVIF", "create image variants"…
secondsky/claude-skills
Deploy Next.js to Cloudflare Workers via the OpenNext adapter (@opennextjs/cloudflare).
secondsky/claude-skills
Cloudflare Sandboxes SDK for secure code execution in Linux containers at edge.
Works with
Categories
TypeScript-first schema validation and type inference. An agent skill from secondsky/claude-skills. Zod is an agent skill from secondsky/claude-skills. TypeScript-first schema validation and type inference.
Zod fits situations like: validating API requests/responses; defining type-safe schemas with runtime validation; transforming data; generating JSON Schema for OpenAPI/AI.
Run `npx skills add secondsky/claude-skills --skill zod -a claude-code`. Or copy the skill folder (plugins/zod/skills/zod in secondsky/claude-skills) into .claude/skills/zod in your project. Claude Code loads it when a task matches its description.
Run `npx skills add secondsky/claude-skills --skill zod -a codex`. Or copy the skill folder (plugins/zod/skills/zod in secondsky/claude-skills) into .agents/skills/zod in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add secondsky/claude-skills --skill zod -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, .gemini/skills/zod, .github/skills/zod and .opencode/skills/zod in your project.
Going by SKILL.md and its folder, Zod needs TypeScript and JavaScript for the scripts in its folder, the command-line tools its instructions call (bun, npm, pnpm and yarn) and credentials named API_KEY. Our summary lists: Node.js.
SKILL.md names 4 domains. As links in the text: zod.dev, github.com, zod-playground.vercel.app and trpc.io. This is read from the text; nothing was executed.
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.
Zod is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 7k tokens (SKILL.md is roughly 28k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 28k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Zod: Mastra Hono (jwynia/agent-skills, 165 stars), Desloppify (databuddy-analytics/Databuddy, 1.2k stars), Type Safety (idavidov13/agentic-playwright, 223 stars) and Zod Validation Expert (davila7/claude-code-templates, 32k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
secondsky (a GitHub user) maintains it in secondsky/claude-skills, which has 227 GitHub stars. The repository holds 169 skills in this directory. The repository was last updated on September 28, 2026.
Source: secondsky/claude-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.