yup

Schema validation library with a fluent, chainable API for JavaScript and TypeScript.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "yup" with this command: npx skills add majiayu000/claude-skill-registry/majiayu000-claude-skill-registry-yup

Yup

Schema validation library with a fluent, chainable API for JavaScript and TypeScript.

Quick Start

npm install yup

import * as yup from 'yup';

const schema = yup.object({ name: yup.string().required(), email: yup.string().email().required(), age: yup.number().positive().integer(), });

// Validate const data = await schema.validate({ name: 'John', email: 'john@example.com' });

// Check validity const isValid = await schema.isValid(data);

Schema Types

String

yup.string() .required('Name is required') .min(2, 'At least 2 characters') .max(50, 'At most 50 characters') .matches(/^[a-zA-Z]+$/, 'Only letters') .email('Invalid email') .url('Invalid URL') .uuid('Invalid UUID') .lowercase() .uppercase() .trim() .default('Anonymous')

Number

yup.number() .required('Required') .min(0, 'Must be positive') .max(100, 'Max 100') .positive('Must be positive') .negative('Must be negative') .integer('Must be integer') .moreThan(0, 'Greater than 0') .lessThan(100, 'Less than 100') .truncate() .round() .default(0)

Boolean

yup.boolean() .required() .isTrue('Must accept terms') .isFalse() .default(false)

Date

yup.date() .required() .min(new Date(), 'Must be in the future') .max(new Date('2030-12-31'), 'Too far ahead') .default(() => new Date())

Array

yup.array() .of(yup.string().required()) .min(1, 'At least one item') .max(5, 'At most 5 items') .required() .default([])

// Tuple-like array yup.tuple([ yup.string().required(), yup.number().required(), ])

Object

yup.object({ name: yup.string().required(), age: yup.number().positive(), }) .noUnknown() // Reject unknown keys .strict() // Don't coerce types

Mixed (Any Type)

yup.mixed() .oneOf(['option1', 'option2'], 'Must be option1 or option2') .notOneOf(['forbidden']) .required()

Common Patterns

User Registration

const registrationSchema = yup.object({ email: yup.string() .email('Invalid email') .required('Email is required'),

password: yup.string() .min(8, 'At least 8 characters') .matches(/[a-z]/, 'Need lowercase letter') .matches(/[A-Z]/, 'Need uppercase letter') .matches(/[0-9]/, 'Need number') .required('Password is required'),

confirmPassword: yup.string() .oneOf([yup.ref('password')], 'Passwords must match') .required('Confirm password'),

age: yup.number() .positive() .integer() .min(18, 'Must be 18+') .required('Age is required'),

terms: yup.boolean() .isTrue('Must accept terms'), });

Address

const addressSchema = yup.object({ street: yup.string().required(), city: yup.string().required(), state: yup.string().length(2).required(), zip: yup.string() .matches(/^\d{5}(-\d{4})?$/, 'Invalid ZIP') .required(), country: yup.string().default('US'), });

Payment

const paymentSchema = yup.object({ cardNumber: yup.string() .matches(/^\d{16}$/, 'Invalid card number') .required(),

expiry: yup.string() .matches(/^(0[1-9]|1[0-2])/\d{2}$/, 'MM/YY format') .required(),

cvv: yup.string() .matches(/^\d{3,4}$/, 'Invalid CVV') .required(),

amount: yup.number() .positive() .required(), });

Conditional Validation

when() - Field Dependencies

const schema = yup.object({ hasCompany: yup.boolean(),

companyName: yup.string().when('hasCompany', { is: true, then: (schema) => schema.required('Company name required'), otherwise: (schema) => schema.notRequired(), }), });

Multiple Conditions

const schema = yup.object({ type: yup.string().oneOf(['personal', 'business']), taxId: yup.string(), ssn: yup.string(), }).test('tax-info', 'Tax info required', function(value) { if (value.type === 'business') { return !!value.taxId; } return !!value.ssn; });

Custom Validation

test() Method

const schema = yup.string().test( 'is-valid-username', 'Username already taken', async (value) => { if (!value) return true; const available = await checkUsername(value); return available; } );

With Context

const schema = yup.object({ password: yup.string().required(), confirmPassword: yup.string() .test('passwords-match', 'Passwords must match', function(value) { return value === this.parent.password; }), });

addMethod() - Reusable Validators

yup.addMethod(yup.string, 'phone', function(message) { return this.test('phone', message || 'Invalid phone', (value) => { if (!value) return true; return /^+?[\d\s-()]+$/.test(value); }); });

// Usage const schema = yup.object({ phone: yup.string().phone('Invalid phone number'), });

Type Inference

InferType

const userSchema = yup.object({ name: yup.string().required(), email: yup.string().email().required(), age: yup.number().positive(), });

type User = yup.InferType<typeof userSchema>; // { name: string; email: string; age: number | undefined }

With Defaults

const schema = yup.object({ role: yup.string().default('user'), active: yup.boolean().default(true), });

type Config = yup.InferType<typeof schema>; // { role: string; active: boolean }

Transformation

cast() - Transform Values

const schema = yup.string().trim().lowercase(); const result = schema.cast(' HELLO '); // 'hello'

transform() - Custom Transforms

const schema = yup.string().transform((value) => { return value?.replace(/\s+/g, ' ').trim(); });

Object Transform

const schema = yup.object({ firstName: yup.string(), lastName: yup.string(), }).transform((value) => ({ ...value, fullName: ${value.firstName} ${value.lastName}, }));

Validation Options

validate()

try { const result = await schema.validate(data, { abortEarly: false, // Collect all errors stripUnknown: true, // Remove unknown keys strict: false, // Allow coercion context: { user: currentUser }, }); } catch (err) { if (err instanceof yup.ValidationError) { console.log(err.errors); // All error messages console.log(err.inner); // Detailed errors } }

validateSync()

try { const result = schema.validateSync(data); } catch (err) { // Handle error }

isValid()

const valid = await schema.isValid(data);

React Hook Form Integration

import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup';

const schema = yup.object({ email: yup.string().email().required(), password: yup.string().min(8).required(), });

type FormData = yup.InferType<typeof schema>;

function Form() { const { register, handleSubmit, formState: { errors } } = useForm<FormData>({ resolver: yupResolver(schema), });

return ( <form onSubmit={handleSubmit(onSubmit)}> <input {...register('email')} /> {errors.email && <span>{errors.email.message}</span>}

  &#x3C;input {...register('password')} type="password" />
  {errors.password &#x26;&#x26; &#x3C;span>{errors.password.message}&#x3C;/span>}

  &#x3C;button type="submit">Submit&#x3C;/button>
&#x3C;/form>

); }

Formik Integration

import { Formik, Form, Field, ErrorMessage } from 'formik';

const schema = yup.object({ email: yup.string().email().required(), });

function MyForm() { return ( <Formik initialValues={{ email: '' }} validationSchema={schema} onSubmit={handleSubmit} > <Form> <Field name="email" type="email" /> <ErrorMessage name="email" /> <button type="submit">Submit</button> </Form> </Formik> ); }

See references/methods.md for complete method reference.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

frontend-design

No summary provided by upstream source.

Repository SourceNeeds Review
General

ui-ux-pro-max

No summary provided by upstream source.

Repository SourceNeeds Review
General

planning

No summary provided by upstream source.

Repository SourceNeeds Review
General

sequential-thinking

No summary provided by upstream source.

Repository SourceNeeds Review