Agent skill

Valibot

by aidenlx in aidenlx/zotlit

Schema validation with Valibot, the modular and type-safe schema library.

MITAuto-check passedFrontend & Design

Install Valibot

skills CLI
$ npx skills add aidenlx/zotlit --skill valibot -a claude-code

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

GitHub CLI
$ gh skill install aidenlx/zotlit valibot --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/aidenlx/zotlit.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/valibot .claude/skills/valibot && 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
valibot
GitHub stars
1k
Token cost
~4.7k tokens
SKILL.md length
620 words
Files
1
Skills in repo
16
Repo updated
First seen
Licence
MIT

At a glance

Schema validation with Valibot, the modular and type-safe schema library.

  • Works in 3 steps: Schemas → Methods → Actions
  • The user needs to validate data
  • SKILL.md covers When to use this skill, CRITICAL: Valibot vs Zod — Do…, Installation and Mental Model, plus 5 more sections
  • Calls npm, yarn and pnpm; needs API_KEY

What it does

Valibot is an agent skill from aidenlx/zotlit. Schema validation with Valibot, the modular and type-safe schema library. Use when the user needs to validate data, create schemas, parse inputs, or work with Valibot in their project. Also use when migrating from Zod to Valibot.

Its SKILL.md is about 4.7k 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 and Type safety. It works with Zod. The repository describes itself as: Bring your Zotero library into Obsidian. Create literature notes, insert citations, and annotate PDFs without leaving your vault. The licence is MIT.

When your agent uses it

  • The user needs to validate data
  • Work with Valibot in their project
  • Migrating from Zod to Valibot

Example prompts

  • “/valibot”

Requirements

  • Node.js

Workflow steps

3 steps, taken from the step headings in SKILL.md.

  1. Schemas
  2. Methods
  3. Actions

What it can do on your machine

Read from SKILL.md and the folder at commit 27f5752. 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:

    • npm
    • yarn
    • pnpm
    • bun

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

  • Network

    Links to these hosts (documentation or services it may open):

    • valibot.dev
    • github.com

    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

Valibot loads about 4.7k tokens when it runs. Until then it costs about 59 tokens; SKILL.md has 620 words of instructions outside code blocks.

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

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 aidenlx/zotlit at commit 27f5752, republished under its MIT licence (© aidenlx). 620 words, ~4,716 tokens.

Download SKILL.mdSave it as .claude/skills/valibot/SKILL.md (or your agent's skills folder).
name
valibot
description
Schema validation with Valibot, the modular and type-safe schema library. Use when the user needs to validate data, create schemas, parse inputs, or work with Valibot in their project. Also use when migrating from Zod to Valibot.
license
MIT
metadata.author
open-circle
metadata.version
1.0

Valibot

This skill helps you work effectively with Valibot, the modular and type-safe schema library for validating structural data.

When to use this skill

  • When the user asks about schema validation with Valibot
  • When creating or modifying Valibot schemas
  • When parsing or validating user input
  • When the user mentions Valibot, schema, or validation
  • When migrating from Zod to Valibot

CRITICAL: Valibot vs Zod — Do Not Confuse!

Valibot and Zod have different APIs. Never mix them up!

Key Differences
FeatureZod ❌Valibot ✅
Importimport { z } from 'zod'import * as v from 'valibot'
ValidationsChained methods: .email().min(5)Pipeline: v.pipe(v.string(), v.email(), v.minLength(5))
Parsingschema.parse(data)v.parse(schema, data)
Safe parsingschema.safeParse(data)v.safeParse(schema, data)
Optionalz.string().optional()v.optional(v.string())
Nullablez.string().nullable()v.nullable(v.string())
Defaultz.string().default('x')v.optional(v.string(), 'x')
Transformz.string().transform(fn)v.pipe(v.string(), v.transform(fn))
Refine/Checkz.string().refine(fn)v.pipe(v.string(), v.check(fn))
Enumz.enum(['a', 'b'])v.picklist(['a', 'b'])
Native enumz.nativeEnum(MyEnum)v.enum(MyEnum)
Unionz.union([a, b])v.union([a, b])
Discriminated unionz.discriminatedUnion('type', [...])v.variant('type', [...])
Intersectionz.intersection(a, b)v.intersect([a, b])
Min/max length.min(5).max(10)v.minLength(5), v.maxLength(10)
Min/max value.gte(5).lte(10)v.minValue(5), v.maxValue(10)
Infer typez.infer<typeof Schema>v.InferOutput<typeof Schema>
Infer inputz.input<typeof Schema>v.InferInput<typeof Schema>
Common Mistakes to Avoid
typescript
// ❌ WRONG - This is Zod syntax, NOT Valibot!
const Schema = v.string().email().min(5);
const result = Schema.parse(data);

// ✅ CORRECT - Valibot uses functions and pipelines
const Schema = v.pipe(v.string(), v.email(), v.minLength(5));
const result = v.parse(Schema, data);
typescript
// ❌ WRONG - Zod-style optional
const Schema = v.object({
  name: v.string().optional(),
});

// ✅ CORRECT - Valibot wraps with optional()
const Schema = v.object({
  name: v.optional(v.string()),
});
typescript
// ❌ WRONG - Zod-style default
const Schema = v.string().default("hello");

// ✅ CORRECT - Valibot uses second argument
const Schema = v.optional(v.string(), "hello");

Installation

bash
npm install valibot     # npm
yarn add valibot        # yarn
pnpm add valibot        # pnpm
bun add valibot         # bun

Import with a wildcard (recommended):

typescript
import * as v from "valibot";

Or with individual imports:

typescript
import { object, string, pipe, email, parse } from "valibot";

Mental Model

Valibot's API is divided into three main concepts:

1. Schemas

Schemas define the expected data type. They are the starting point.

typescript
import * as v from "valibot";

// Primitive schemas
const StringSchema = v.string();
const NumberSchema = v.number();
const BooleanSchema = v.boolean();
const DateSchema = v.date();

// Complex schemas
const ArraySchema = v.array(v.string());
const ObjectSchema = v.object({
  name: v.string(),
  age: v.number(),
});
2. Methods

Methods help you use or modify schemas. The schema is always the first argument.

typescript
// Parsing
const result = v.parse(StringSchema, "hello");
const safeResult = v.safeParse(StringSchema, "hello");

// Type guard
if (v.is(StringSchema, data)) {
  // data is typed as string
}
3. Actions

Actions validate or transform data within a pipe(). They MUST be used inside pipelines.

typescript
// Actions are used in pipe()
const EmailSchema = v.pipe(
  v.string(),
  v.trim(),
  v.email(),
  v.endsWith("@example.com"),
);

Pipelines

Pipelines extend schemas with validation and transformation actions. A pipeline always starts with a schema, followed by actions.

typescript
import * as v from "valibot";

const UsernameSchema = v.pipe(
  v.string(),
  v.trim(),
  v.minLength(3, "Username must be at least 3 characters"),
  v.maxLength(20, "Username must be at most 20 characters"),
  v.regex(
    /^[a-z0-9_]+$/i,
    "Username can only contain letters, numbers, and underscores",
  ),
);

const AgeSchema = v.pipe(
  v.number(),
  v.integer("Age must be a whole number"),
  v.minValue(0, "Age cannot be negative"),
  v.maxValue(150, "Age cannot exceed 150"),
);
Common Validation Actions

String validations:

  • v.email() — Valid email format
  • v.url() — Valid URL format
  • v.uuid() — Valid UUID format
  • v.regex(pattern) — Match regex pattern
  • v.minLength(n) — Minimum length
  • v.maxLength(n) — Maximum length
  • v.length(n) — Exact length
  • v.nonEmpty() — Not empty string
  • v.startsWith(str) — Starts with string
  • v.endsWith(str) — Ends with string
  • v.includes(str) — Contains string

Number validations:

  • v.minValue(n) — Minimum value (>=)
  • v.maxValue(n) — Maximum value (<=)
  • v.gtValue(n) — Greater than (>)
  • v.ltValue(n) — Less than (<)
  • v.integer() — Must be integer
  • v.finite() — Must be finite
  • v.safeInteger() — Safe integer range
  • v.multipleOf(n) — Must be multiple of n

Array validations:

  • v.minLength(n) — Minimum items
  • v.maxLength(n) — Maximum items
  • v.length(n) — Exact item count
  • v.nonEmpty() — At least one item
  • v.includes(item) — Contains item
  • v.excludes(item) — Does not contain item
Custom Validation with check()
typescript
const PasswordSchema = v.pipe(
  v.string(),
  v.minLength(8),
  v.check(
    (input) => /[A-Z]/.test(input),
    "Password must contain an uppercase letter",
  ),
  v.check((input) => /[0-9]/.test(input), "Password must contain a number"),
);
Show full SKILL.md (255 more words)Show less
Value Transformations

These actions modify the value without changing its type:

String transformations:

  • v.trim() — Remove leading/trailing whitespace
  • v.trimStart() — Remove leading whitespace
  • v.trimEnd() — Remove trailing whitespace
  • v.toLowerCase() — Convert to lowercase
  • v.toUpperCase() — Convert to uppercase

Number transformations:

  • v.toMinValue(n) — Clamp to minimum value (if less than n, set to n)
  • v.toMaxValue(n) — Clamp to maximum value (if greater than n, set to n)
typescript
const NormalizedEmailSchema = v.pipe(
  v.string(),
  v.trim(),
  v.toLowerCase(),
  v.email(),
);

// Clamp number to range 0-100
const PercentageSchema = v.pipe(v.number(), v.toMinValue(0), v.toMaxValue(100));
Type Transformations

For converting between data types, use these built-in transformation actions:

  • v.toNumber() — Convert to number
  • v.toString() — Convert to string
  • v.toBoolean() — Convert to boolean
  • v.toBigint() — Convert to bigint
  • v.toDate() — Convert to Date
typescript
// Convert string to number
const PortSchema = v.pipe(v.string(), v.toNumber(), v.integer(), v.minValue(1));

// Convert ISO string to Date
const TimestampSchema = v.pipe(v.string(), v.isoDateTime(), v.toDate());

// Convert to boolean
const FlagSchema = v.pipe(v.string(), v.toBoolean());
Custom Transformations

For custom transformations, use v.transform():

typescript
const DateStringSchema = v.pipe(
  v.string(),
  v.isoDate(),
  v.transform((input) => new Date(input)),
);

// Custom object transformation
const UserSchema = v.pipe(
  v.object({
    firstName: v.string(),
    lastName: v.string(),
  }),
  v.transform((input) => ({
    ...input,
    fullName: `${input.firstName} ${input.lastName}`,
  })),
);

Object Schemas

Basic Object
typescript
const UserSchema = v.object({
  id: v.number(),
  name: v.string(),
  email: v.pipe(v.string(), v.email()),
  age: v.optional(v.number()),
});

type User = v.InferOutput<typeof UserSchema>;
Object Variants
typescript
// Regular object - strips unknown keys (default)
const ObjectSchema = v.object({ key: v.string() });

// Loose object - allows and preserves unknown keys
const LooseObjectSchema = v.looseObject({ key: v.string() });

// Strict object - throws on unknown keys
const StrictObjectSchema = v.strictObject({ key: v.string() });

// Object with rest - validates unknown keys against a schema
const ObjectWithRestSchema = v.objectWithRest(
  { key: v.string() },
  v.number(), // unknown keys must be numbers
);
Optional and Nullable Fields
typescript
const ProfileSchema = v.object({
  // Required
  name: v.string(),

  // Optional (can be undefined or missing)
  nickname: v.optional(v.string()),

  // Optional with default
  role: v.optional(v.string(), "user"),

  // Nullable (can be null)
  avatar: v.nullable(v.string()),

  // Nullish (can be null or undefined)
  bio: v.nullish(v.string()),

  // Nullish with default
  theme: v.nullish(v.string(), "light"),
});
Object Methods
typescript
const BaseSchema = v.object({
  id: v.number(),
  name: v.string(),
  email: v.string(),
  password: v.string(),
});

// Pick specific keys
const PublicUserSchema = v.pick(BaseSchema, ["id", "name"]);

// Omit specific keys
const UserWithoutPasswordSchema = v.omit(BaseSchema, ["password"]);

// Make all optional
const PartialUserSchema = v.partial(BaseSchema);

// Make all required
const RequiredUserSchema = v.required(PartialUserSchema);

// Merge objects
const ExtendedUserSchema = v.object({
  ...BaseSchema.entries,
  createdAt: v.date(),
});
Cross-Field Validation
typescript
const RegistrationSchema = v.pipe(
  v.object({
    password: v.pipe(v.string(), v.minLength(8)),
    confirmPassword: v.string(),
  }),
  v.forward(
    v.partialCheck(
      [["password"], ["confirmPassword"]],
      (input) => input.password === input.confirmPassword,
      "Passwords do not match",
    ),
    ["confirmPassword"],
  ),
);

Arrays and Tuples

Arrays
typescript
const TagsSchema = v.pipe(
  v.array(v.string()),
  v.minLength(1, "At least one tag required"),
  v.maxLength(10, "Maximum 10 tags allowed"),
);

// Array of objects
const UsersSchema = v.array(
  v.object({
    id: v.number(),
    name: v.string(),
  }),
);
Tuples
typescript
// Fixed-length array with specific types
const CoordinatesSchema = v.tuple([v.number(), v.number()]);
// Type: [number, number]

// Tuple with rest
const ArgsSchema = v.tupleWithRest(
  [v.string()], // first arg is string
  v.number(), // rest are numbers
);
// Type: [string, ...number[]]

Unions and Variants

Union
typescript
const StringOrNumberSchema = v.union([v.string(), v.number()]);

const StatusSchema = v.union([
  v.literal("pending"),
  v.literal("active"),
  v.literal("inactive"),
]);
Picklist (for string/number literals)
typescript
// Simpler than union of literals
const StatusSchema = v.picklist(["pending", "active", "inactive"]);

const PrioritySchema = v.picklist([1, 2, 3]);
Variant (discriminated union)

Use variant for better performance with discriminated unions:

typescript
const EventSchema = v.variant("type", [
  v.object({
    type: v.literal("click"),
    x: v.number(),
    y: v.number(),
  }),
  v.object({
    type: v.literal("keypress"),
    key: v.string(),
  }),
  v.object({
    type: v.literal("scroll"),
    direction: v.picklist(["up", "down"]),
  }),
]);

Parsing Data

parse() — Throws on Error
typescript
import * as v from "valibot";

const EmailSchema = v.pipe(v.string(), v.email());

try {
  const email = v.parse(EmailSchema, "jane@example.com");
  console.log(email); // 'jane@example.com'
} catch (error) {
  console.error(error); // ValiError
}
safeParse() — Returns Result Object
typescript
const result = v.safeParse(EmailSchema, input);

if (result.success) {
  console.log(result.output); // Valid data
} else {
  console.log(result.issues); // Array of issues
}
is() — Type Guard
typescript
if (v.is(EmailSchema, input)) {
  // input is typed as string
}
Configuration Options
typescript
// Abort early - stop at first error
v.parse(Schema, data, { abortEarly: true });

// Abort pipe early - stop pipeline at first error
v.parse(Schema, data, { abortPipeEarly: true });

Type Inference

typescript
import * as v from "valibot";

const UserSchema = v.object({
  name: v.string(),
  age: v.pipe(v.string(), v.transform(Number)),
  role: v.optional(v.string(), "user"),
});

// Output type (after transformations and defaults)
type User = v.InferOutput<typeof UserSchema>;
// { name: string; age: number; role: string }

// Input type (before transformations)
type UserInput = v.InferInput<typeof UserSchema>;
// { name: string; age: string; role?: string | undefined }

// Issue type
type UserIssue = v.InferIssue<typeof UserSchema>;

Error Handling

Custom Error Messages
typescript
const LoginSchema = v.object({
  email: v.pipe(
    v.string("Email must be a string"),
    v.nonEmpty("Please enter your email"),
    v.email("Invalid email format"),
  ),
  password: v.pipe(
    v.string("Password must be a string"),
    v.nonEmpty("Please enter your password"),
    v.minLength(8, "Password must be at least 8 characters"),
  ),
});
Flattening Errors
typescript
const result = v.safeParse(LoginSchema, data);

if (!result.success) {
  const flat = v.flatten(result.issues);
  // { nested: { email: ['Invalid email format'], password: ['...'] } }
}
Issue Structure

Each issue contains:

  • kind: 'schema' | 'validation' | 'transformation'
  • type: Function name (e.g., 'string', 'email', 'min_length')
  • input: The problematic input
  • expected: What was expected
  • received: What was received
  • message: Human-readable message
  • path: Array of path items for nested issues

Fallback Values

typescript
// Static fallback
const NumberSchema = v.fallback(v.number(), 0);
v.parse(NumberSchema, "invalid"); // Returns 0

// Dynamic fallback
const DateSchema = v.fallback(v.date(), () => new Date());

Recursive Schemas

typescript
import * as v from "valibot";

type TreeNode = {
  value: string;
  children: TreeNode[];
};

const TreeNodeSchema: v.GenericSchema<TreeNode> = v.object({
  value: v.string(),
  children: v.lazy(() => v.array(TreeNodeSchema)),
});

Async Validation

For async operations (e.g., database checks), use async variants:

typescript
import * as v from "valibot";

const isUsernameAvailable = async (username: string) => {
  // Check database
  return true;
};

const UsernameSchema = v.pipeAsync(
  v.string(),
  v.minLength(3),
  v.checkAsync(isUsernameAvailable, "Username is already taken"),
);

// Must use parseAsync
const username = await v.parseAsync(UsernameSchema, "john");

JSON Schema Conversion

typescript
import { toJsonSchema } from "@valibot/to-json-schema";
import * as v from "valibot";

const EmailSchema = v.pipe(v.string(), v.email());
const jsonSchema = toJsonSchema(EmailSchema);
// { type: 'string', format: 'email' }

Naming Conventions

typescript
export const User = v.object({
  name: v.string(),
  email: v.pipe(v.string(), v.email()),
});

export type User = v.InferOutput<typeof User>;

// Usage
const users: User[] = [];
users.push(v.parse(User, data));
typescript
export const UserSchema = v.object({
  name: v.string(),
  age: v.pipe(v.string(), v.transform(Number)),
});

export type UserInput = v.InferInput<typeof UserSchema>;
export type UserOutput = v.InferOutput<typeof UserSchema>;

Common Patterns

Login Form
typescript
const LoginSchema = v.object({
  email: v.pipe(
    v.string(),
    v.nonEmpty("Please enter your email"),
    v.email("Invalid email address"),
  ),
  password: v.pipe(
    v.string(),
    v.nonEmpty("Please enter your password"),
    v.minLength(8, "Password must be at least 8 characters"),
  ),
});
API Response
typescript
const ApiResponseSchema = v.variant("status", [
  v.object({
    status: v.literal("success"),
    data: v.unknown(),
  }),
  v.object({
    status: v.literal("error"),
    error: v.object({
      code: v.string(),
      message: v.string(),
    }),
  }),
]);
Environment Variables
typescript
const EnvSchema = v.object({
  NODE_ENV: v.picklist(["development", "production", "test"]),
  PORT: v.pipe(v.string(), v.transform(Number), v.integer(), v.minValue(1)),
  DATABASE_URL: v.pipe(v.string(), v.url()),
  API_KEY: v.pipe(v.string(), v.minLength(32)),
});

const env = v.parse(EnvSchema, process.env);
Date Handling
typescript
// String to Date
const DateFromStringSchema = v.pipe(
  v.string(),
  v.isoDate(),
  v.transform((input) => new Date(input)),
);

// Date validation
const FutureDateSchema = v.pipe(
  v.date(),
  v.minValue(new Date(), "Date must be in the future"),
);

Additional Resources

© aidenlx, MIT. 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 .agents/skills/valibot of aidenlx/zotlit.

Open the folder on GitHubat commit 27f5752

Compare with similar skills

Valibot 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.

Valibot compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Valibot this skillaidenlx/zotlit1k—~4.7kAutomated safety check: PassMIT
Nuxt Contentsecondsky/claude-skills227—~4.3kAutomated safety check: PassMIT
React Hook Form Zodsecondsky/claude-skills227—~4.8kAutomated safety check: PassMIT
Typescript Patternssoftspark/ai-toolkit179—~1.6kAutomated safety check: PassApache-2.0
Zod Validation Utilitiesgiuseppe-trisciuoglio/developer-kit356—~1.7kAutomated safety check: NotesMIT
Zodjasonjgardner/blockbench-mcp-plugin4953 repos~1.4kAutomated safety check: PassGPL-3.0

Similar skills

  • Nuxt Content

    secondsky/claude-skills

    Nuxt Content v3 Git-based CMS for Markdown/MDC content sites.

    227 GitHub stars~4.3k tokensUpdated 11 days ago
    Frontend & DesignAuto-check passed
  • React Hook Form Zod

    secondsky/claude-skills

    Type-safe React forms with React Hook Form and Zod validation.

    227 GitHub stars~4.8k tokensUpdated 11 days ago
    Frontend & DesignAuto-check passed
  • 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
  • Zod Validation Utilities

    giuseppe-trisciuoglio/developer-kit

    Creates reusable Zod v4 schemas, validates API payloads, forms, and configuration input, transforms and coerces data safely, and handles validation errors with strong type inference for TypeScript…

    356 GitHub stars~1.7k tokensUpdated 29 days ago
    Frontend & DesignAuto-check: notes
  • Zod

    jasonjgardner/blockbench-mcp-plugin

    Zod schema validation best practices for type safety, parsing, and error handling.

    495 GitHub starsUsed in 3 repos~1.4k tokens
    DevelopmentAuto-check passed
  • Hono Idioms

    irahardianto/awesome-agv

    Hono lightweight web framework patterns: type-safe route handlers, middleware composition, Zod validation, and RPC clients for Cloudflare Workers, Node, or Bun.

    157 GitHub stars~3k tokensUpdated 4 days ago
    DevelopmentAuto-check passed

More from aidenlx/zotlit

All 16 skills in this repo
  • I18n UI Text

    aidenlx/zotlit

    Obsidian house style for the wording of user-facing UI strings — command names, setting labels, button text, notices, modal copy.

    1k GitHub stars~2.8k tokensUpdated today
    Auto-check passed
  • Obsidian CSS

    aidenlx/zotlit

    Style Obsidian plugin UI with Tailwind + native components. An agent skill from aidenlx/zotlit.

    1k GitHub stars~4.8k tokensUpdated today
    Auto-check passed
  • Arkregex

    aidenlx/zotlit

    Typed regex authoring with arkregex in this repo. An agent skill from aidenlx/zotlit.

    1k GitHub stars~952 tokensUpdated today
    Auto-check passed
  • Changelog Entry

    aidenlx/zotlit

    Write a user-facing changelog entry under apps/docs/content/changelog/.

    1k GitHub stars~1.6k tokensUpdated today
    Auto-check passed
  • Discord Announcement

    aidenlx/zotlit

    Draft a Discord announcement from a changelog entry. An agent skill from aidenlx/zotlit.

    1k GitHub stars~604 tokensUpdated today
    Auto-check passed
  • Inlang I18n

    aidenlx/zotlit

    Define ZotLit UI messages in the Inlang Message Format and consume them through the generated JSON Language Pack facade.

    1k GitHub stars~1k tokensUpdated today
    Auto-check passed

Works with

Questions about Valibot

What does Valibot do?

Schema validation with Valibot, the modular and type-safe schema library. Valibot is an agent skill from aidenlx/zotlit. Schema validation with Valibot, the modular and type-safe schema library.

When should I use Valibot?

Valibot fits situations like: the user needs to validate data; work with Valibot in their project; migrating from Zod to Valibot.

How do I install Valibot in Claude Code?

Run `npx skills add aidenlx/zotlit --skill valibot -a claude-code`. Or copy the skill folder (.agents/skills/valibot in aidenlx/zotlit) into .claude/skills/valibot in your project. Claude Code loads it when a task matches its description.

How do I install Valibot in Codex?

Run `npx skills add aidenlx/zotlit --skill valibot -a codex`. Or copy the skill folder (.agents/skills/valibot in aidenlx/zotlit) into .agents/skills/valibot in your project. Codex loads it when a task matches its description.

Can I use Valibot 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 aidenlx/zotlit --skill valibot -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/valibot, .gemini/skills/valibot, .github/skills/valibot and .opencode/skills/valibot in your project.

What does Valibot need to run?

Going by SKILL.md and its folder, Valibot needs the command-line tools its instructions call (npm, yarn, pnpm and bun) and credentials named API_KEY. Our summary lists: Node.js.

Does Valibot access the network?

SKILL.md names 2 domains. As links in the text: valibot.dev and github.com. This is read from the text; nothing was executed.

Is Valibot 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 Valibot use?

Valibot is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Valibot use?

About 4.7k tokens (SKILL.md is roughly 19k 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 Valibot?

Skills that share tags, products or a category with Valibot: Nuxt Content (secondsky/claude-skills, 227 stars), React Hook Form Zod (secondsky/claude-skills, 227 stars), Typescript Patterns (softspark/ai-toolkit, 179 stars) and Zod Validation Utilities (giuseppe-trisciuoglio/developer-kit, 356 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Valibot?

aidenlx (a GitHub user) maintains it in aidenlx/zotlit, which has 1,028 GitHub stars. The repository holds 16 skills in this directory. The repository was last updated on October 9, 2026.

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