March 28, 20263 min read

1. Basic User Profile Schema
This schema is great for a user profile or signup form that requires a name, email, and phone number.
import * as yup from 'yup';
const userProfileSchema = yup.object().shape({
name: yup
.string()
.min(2, 'Name must be at least 2 characters long')
.max(50, 'Name must be less than 50 characters')
.required('Name is required'),
email: yup
.string()
.email('Invalid email format')
.required('Email is required'),
phone: yup
.string()
.matches(
/^[0-9]{10,15}$/,
'Phone number must contain only digits (10-15 characters)'
)
.required('Phone number is required'),
});
const userProfileData = {
name: 'Jane Doe',
email: 'jane.doe@example.com',
phone: '1234567890',
};
userProfileSchema
.validate(userProfileData)
.then(valid => console.log('Valid user profile data:', valid))
.catch(err => console.log('Validation error:', err.errors));
Key Points:
minandmaxhelp keep string inputs within a certain length.matchesensures phone number follows a digit-only format.requiredguarantees a field is present and not empty.
2. Blog Post Schema
If you’re working with a blogging platform or content management system, this schema can help validate a new blog post’s title, content, and tags.
import * as yup from 'yup';
const blogPostSchema = yup.object().shape({
title: yup
.string()
.min(5, 'Title must be at least 5 characters')
.required('Title is required'),
content: yup
.string()
.min(20, 'Content must be at least 20 characters')
.required('Content is required'),
tags: yup
.array()
.of(yup.string().min(2, 'Each tag must have at least 2 characters'))
.max(10, 'You can only have up to 10 tags')
.required('Please include at least one tag'),
});
const blogPostData = {
title: 'How to Master JavaScript',
content: 'JavaScript is a versatile language used in web development...',
tags: ['javascript', 'web', 'dev'],
};
blogPostSchema
.validate(blogPostData)
.then(valid => console.log('Valid blog post data:', valid))
.catch(err => console.log('Validation error:', err.errors));
Key Points:
array().of(...)ensures each item in thetagsarray meets a certain rule.- You can limit how many items an array may have using
max. - Good for ensuring a certain minimum length for text-based content.
3. Product or E-Commerce Schema
Perfect for an online store, this schema ensures a product has a title, price, and optional stock quantity.
import * as yup from 'yup';
const productSchema = yup.object().shape({
title: yup
.string()
.required('Product title is required')
.max(100, 'Product title cannot exceed 100 characters'),
price: yup
.number()
.typeError('Price must be a number')
.positive('Price must be greater than zero')
.required('Price is required'),
inStock: yup
.number()
.typeError('Stock quantity must be a number')
.integer('Stock quantity must be an integer')
.min(0, 'Stock quantity cannot be negative')
.default(0),
description: yup
.string()
.max(500, 'Description cannot exceed 500 characters')
.nullable(true), // Allows the field to be null or omitted
});
const newProduct = {
title: 'Super Comfy Chair',
price: 79.99,
inStock: 15,
description: 'A very comfortable chair for your living room.',
};
productSchema
.validate(newProduct)
.then(valid => console.log('Valid product data:', valid))
.catch(err => console.log('Validation error:', err.errors));
Key Points:
number().typeError(...)helps ensure the value is actually numeric.positive()andinteger()are great for numeric constraints..default(0)sets a default value ifinStockis omitted..nullable(true)allowsdescriptionto be null or absent if needed.
4. Nested Objects & Date Ranges
If you’re working with bookings, reservations, or any time-based system, you might want to ensure a check-in date is before a check-out date. This example also shows how to use nested objects in Yup.
import * as yup from 'yup';
const dateRangeSchema = yup.object().shape({
user: yup.object().shape({
userId: yup.string().required('User ID is required'),
name: yup.string().required('User name is required'),
}),
startDate: yup.date().required('Check-in date is required'),
endDate: yup
.date()
.required('Check-out date is required')
.min(yup.ref('startDate'), 'Check-out date cannot be before check-in date'),
});
const reservationData = {
user: {
userId: '12345',
name: 'John Wick',
},
startDate: '2025-05-10',
endDate: '2025-05-15',
};
dateRangeSchema
.validate(reservationData)
.then(valid => console.log('Valid reservation:', valid))
.catch(err => console.log('Date range error:', err.errors));
Key Points:
yup.object().shape({...})can be nested, allowing you to validate deeply structured data..min(yup.ref('startDate'))ensuresendDateis the same or afterstartDate.- Useful for flight bookings, hotel reservations, or event scheduling.
5. Web3 Wallet Address Example
If you’re building a dApp or dealing with cryptocurrencies, you may want to validate an Ethereum address or other blockchain wallets.
import * as yup from 'yup';
const ethWalletSchema = yup.string()
.matches(/^0x[a-fA-F0-9]{40}$/, 'Must be a valid Ethereum wallet address')
.required('Wallet address is required');
const userWalletData = {
walletAddress: '0xabcd1234fFfbbb0000CCC9999aaaeee111111111',
};
ethWalletSchema
.validate(userWalletData.walletAddress)
.then(valid => console.log('Valid ETH wallet address:', valid))
.catch(err => console.log('Wallet validation error:', err.errors));
Key Points:
- The schema enforces addresses to start with
0xand follow a 40-character hex format. - This approach can be adapted for other chain addresses if you know the expected pattern.
6. Strictly Enumerated Roles (e.g., Admin, Editor, Viewer)
Sometimes, you want a field to only allow certain string values (like user roles).
import * as yup from 'yup';
const roleSchema = yup.string()
.oneOf(['admin', 'editor', 'viewer'], 'Role must be either admin, editor, or viewer')
.required('User role is required');
roleSchema
.validate('editor')
.then(valid => console.log('Valid role:', valid))
.catch(err => console.log('Role validation error:', err.errors));
Key Points:
.oneOf([...])restricts the value to a specific set of valid options.- Perfect for user permissions or any scenario with a limited set of allowable values.
7. Array of Objects Example (e.g., Items in a Shopping Cart)
Validating arrays of objects? No problem. Here’s an example of items in a cart, each with a product ID, quantity, and price.
import * as yup from 'yup';
const cartItemSchema = yup.object().shape({
productId: yup.string().required('Product ID is required'),
quantity: yup
.number()
.integer('Quantity must be an integer')
.positive('Quantity must be greater than zero')
.required('Quantity is required'),
price: yup
.number()
.positive('Price must be positive')
.required('Price is required'),
});
const shoppingCartSchema = yup.array().of(cartItemSchema);
const myCartData = [
{
productId: 'ABC123',
quantity: 2,
price: 19.99,
},
{
productId: 'XYZ456',
quantity: 1,
price: 59.99,
},
];
shoppingCartSchema
.validate(myCartData)
.then(valid => console.log('Valid cart items:', valid))
.catch(err => console.log('Cart validation error:', err.errors));
Key Points:
yup.array().of(...)allows you to define the schema for each item in an array.- Each item must adhere to the shape defined by
cartItemSchema. - Handy for validating any “list of objects” scenario (e.g., cart items, tasks, etc.).
8. Credit Card and Expiration Date
Finally, a common use case for e-commerce sites is validating credit card information. Below is a simple pattern example (note that real credit card validation can be more nuanced).
import * as yup from 'yup';
const paymentSchema = yup.object().shape({
cardNumber: yup.string()
.matches(/^[0-9]{16}$/, 'Card number must be 16 digits')
.required('Card number is required'),
expiryMonth: yup.number()
.min(1, 'Month cannot be less than 1')
.max(12, 'Month cannot exceed 12')
.required('Expiry month is required'),
expiryYear: yup.number()
.min(new Date().getFullYear(), 'Year must be this year or greater')
.required('Expiry year is required'),
cvc: yup.string()
.matches(/^[0-9]{3,4}$/, 'CVC must be 3 or 4 digits')
.required('CVC is required'),
});
const paymentData = {
cardNumber: '1234567812345678',
expiryMonth: 12,
expiryYear: 2030,
cvc: '123',
};
paymentSchema
.validate(paymentData)
.then(valid => console.log('Valid payment data:', valid))
.catch(err => console.log('Payment validation error:', err.errors));
Key Points:
- This uses simple numeric constraints for month and year.
- CVC can be 3 or 4 digits depending on the card type.
- Real-world credit card checks might involve using a Luhn algorithm or further checks.
Tips for Structuring Yup Schemas
- Combine Schemas: You can define multiple smaller schemas and combine them if your data is spread across different sections (for example, user details, address, and payment).
- Custom Methods and Validation: If your logic is more complex, Yup allows for custom tests using
.test(...). - Error Messaging: Provide user-friendly error messages. This makes the validation feedback more meaningful.
Discussion
Have thoughts? Drop them in.
Comments are powered by Disqus. Sign in once, comment anywhere.

