Forms.v
Quick Start (30 seconds)
// Forms.v is a shorthand for Forms.validators
// Both do exactly the same thing!
// Long form
const form1 = Forms.create(
{ email: '' },
{
validators: {
email: Forms.validators.email('Invalid email')
}
}
);
// Short form (same result!)
const form2 = Forms.create(
{ email: '' },
{
validators: {
email: Forms.v.email('Invalid email')
}
}
);
console.log(typeof form1.setValue === typeof form2.setValue); // true
// They're identical!What just happened? You used the shorthand Forms.v instead of typing out Forms.validators. It saves keystrokes and makes your code more concise!
What is Forms.v?
Forms.v is a shorthand alias for Forms.validators.
Simply put, typing Forms.v is exactly the same as typing Forms.validators - they point to the exact same object with the same validation functions.
Think of it like abbreviations in texting:
- "be right back" = "brb" 📱
- "laugh out loud" = "lol" 😂
Forms.validators=Forms.v✨
Same meaning, fewer characters!
Syntax
All of these are identical:
Long Form
Forms.validators.required('Required')
Forms.validators.email('Invalid email')
Forms.validators.minLength(5, 'Too short')Short Form
Forms.v.required('Required')
Forms.v.email('Invalid email')
Forms.v.minLength(5, 'Too short')Both access the exact same validators!
Why Does This Exist?
The Problem with Long Names
When you're writing lots of validations, typing Forms.validators repeatedly gets tedious:
// Long form (lots of typing!)
const form = Forms.create(
{
email: '',
password: '',
confirmPassword: '',
username: '',
age: ''
},
{
validators: {
email: Forms.validators.combine(
Forms.validators.required('Email required'),
Forms.validators.email('Invalid email')
),
password: Forms.validators.combine(
Forms.validators.required('Password required'),
Forms.validators.minLength(8, 'Min 8 characters')
),
confirmPassword: Forms.validators.combine(
Forms.validators.required('Confirmation required'),
Forms.validators.match('password', 'Must match password')
),
username: Forms.validators.combine(
Forms.validators.required('Username required'),
Forms.validators.minLength(3, 'Min 3 characters'),
Forms.validators.maxLength(20, 'Max 20 characters')
),
age: Forms.validators.combine(
Forms.validators.required('Age required'),
Forms.validators.min(18, 'Must be 18+')
)
}
}
);What's the Real Issue?
Typing "Forms.validators" repeatedly
↓
Lots of characters
↓
Hand fatigue
↓
Harder to read
↓
More typosProblems: ❌ Type Forms.validators 14 times in one form! ❌ 17 characters each time (238 characters total!) ❌ Easy to make typos ❌ Code becomes cluttered ❌ Harder to scan visually
The Solution with Forms.v
// Short form (much cleaner!)
const { v } = Forms; // Destructure once
const form = Forms.create(
{
email: '',
password: '',
confirmPassword: '',
username: '',
age: ''
},
{
validators: {
email: v.combine(
v.required('Email required'),
v.email('Invalid email')
),
password: v.combine(
v.required('Password required'),
v.minLength(8, 'Min 8 characters')
),
confirmPassword: v.combine(
v.required('Confirmation required'),
v.match('password', 'Must match password')
),
username: v.combine(
v.required('Username required'),
v.minLength(3, 'Min 3 characters'),
v.maxLength(20, 'Max 20 characters')
),
age: v.combine(
v.required('Age required'),
v.min(18, 'Must be 18+')
)
}
}
);What Just Happened?
Destructure once: const { v } = Forms
↓
Use "v" everywhere
↓
Only 1 character
↓
Cleaner, easier to read
↓
Fewer typosBenefits: ✅ 14 characters total instead of 238 (94% reduction!) ✅ Easier to type and read ✅ Fewer opportunities for typos ✅ Code is more scannable ✅ Same functionality, less noise
Mental Model
Think of Forms.v like a nickname or shortcut:
Real World Analogy
Full Name (Forms.validators):
"Elizabeth Alexandra Mary Windsor"Long, formal, takes time to say.
Nickname (Forms.v):
"Liz"Short, informal, quick to say. Same person!
In Code
Full Name:
Forms.validators.required('Required')
Forms.validators.email('Invalid')
Forms.validators.minLength(5)Nickname:
Forms.v.required('Required')
Forms.v.email('Invalid')
Forms.v.minLength(5)Key Insight: Just like calling someone "Liz" instead of their full name doesn't change who they are, using Forms.v instead of Forms.validators doesn't change what the validators do!
How Does It Work?
Under the Hood
In the library source code, it's literally just an alias:
// Simplified internal code
const validators = {
required: (message) => { /* ... */ },
email: (message) => { /* ... */ },
minLength: (min, message) => { /* ... */ },
// ... all the validators
};
// Export both names
export const Forms = {
validators: validators, // Full name
v: validators, // Shorthand - same object!
create: createForm,
// ... other methods
};Visual Representation
Forms.validators ────┐
├──→ Same Validators Object
Forms.v ─────────────┘Both point to the exact same object in memory!
Proof They're Identical
console.log(Forms.v === Forms.validators);
// true - they're the exact same object!
console.log(Forms.v.required === Forms.validators.required);
// true - same function!
console.log(Object.keys(Forms.v).sort());
console.log(Object.keys(Forms.validators).sort());
// Exact same keys!Basic Usage
Example 1: Using Forms.v Directly
const form = Forms.create(
{ email: '' },
{
validators: {
email: Forms.v.email('Invalid email')
}
}
);
form.setValue('email', 'test@example.com');
console.log(form.isValid); // trueExample 2: Destructuring for Even Shorter Code
// Destructure once at the top
const { v } = Forms;
// Now use 'v' directly
const loginForm = Forms.create(
{ email: '', password: '' },
{
validators: {
email: v.email('Invalid'),
password: v.minLength(8, 'Too short')
}
}
);
const signupForm = Forms.create(
{ username: '', email: '' },
{
validators: {
username: v.minLength(3, 'Too short'),
email: v.email('Invalid')
}
}
);This is the most common pattern! Destructure once, use everywhere.
Example 3: Mixed Usage (Works but Inconsistent)
// You CAN mix them, but it's confusing
const form = Forms.create(
{ email: '', password: '' },
{
validators: {
email: Forms.validators.email('Invalid'), // Long form
password: Forms.v.minLength(8, 'Short') // Short form
}
}
);
// Both work, but pick one style!Comparison: Forms.v vs Forms.validators
Side-by-Side Examples
Example 1: Simple Validation
Using Forms.validators:
const form = Forms.create(
{ email: '' },
{
validators: {
email: Forms.validators.required('Email required')
}
}
);Using Forms.v:
const form = Forms.create(
{ email: '' },
{
validators: {
email: Forms.v.required('Email required')
}
}
);Result: Identical functionality, Forms.v is just shorter.
Example 2: Combined Validators
Using Forms.validators:
const form = Forms.create(
{ password: '' },
{
validators: {
password: Forms.validators.combine(
Forms.validators.required('Password required'),
Forms.validators.minLength(8, 'Min 8 chars')
)
}
}
);Using Forms.v:
const form = Forms.create(
{ password: '' },
{
validators: {
password: Forms.v.combine(
Forms.v.required('Password required'),
Forms.v.minLength(8, 'Min 8 chars')
)
}
}
);Result: Same validation logic, Forms.v saves 38 characters.
Example 3: Destructured
Using Forms.validators (can't destructure cleanly):
// Would need long name
const form = Forms.create(
{ email: '' },
{
validators: {
email: Forms.validators.email('Invalid')
}
}
);Using Forms.v (easy to destructure):
const { v } = Forms;
const form = Forms.create(
{ email: '' },
{
validators: {
email: v.email('Invalid') // Just 'v'!
}
}
);Result: Destructured version is much cleaner with short name.
Character Count Comparison
For a typical form with 5 validated fields:
Forms.validators approach:
Forms.validators.required() // 27 chars
Forms.validators.email() // 24 chars
Forms.validators.minLength() // 28 chars
Forms.validators.maxLength() // 28 chars
Forms.validators.min() // 22 chars
// Total: 129 characters just for the prefix!Forms.v approach:
Forms.v.required() // 18 chars
Forms.v.email() // 15 chars
Forms.v.minLength() // 19 chars
Forms.v.maxLength() // 19 chars
Forms.v.min() // 13 chars
// Total: 84 charactersSavings: 45 characters (35% reduction)
Destructured v approach:
v.required() // 12 chars
v.email() // 9 chars
v.minLength() // 13 chars
v.maxLength() // 13 chars
v.min() // 7 chars
// Total: 54 charactersSavings: 75 characters (58% reduction)
When to Use Which
Use Forms.validators When:
✅ You want maximum clarity for beginners
// Very explicit for learning
Forms.validators.email('Invalid email')
// ^^^^^^^^^
// "Oh, these are validators!"✅ You're writing documentation or tutorials
// Self-documenting
const form = Forms.create(initialValues, {
validators: {
email: Forms.validators.email()
}
});✅ You only have one or two validators
// Not worth destructuring for just one
Forms.validators.required('Required')Use Forms.v When:
✅ You have multiple validators (most common)
const { v } = Forms;
const form = Forms.create(
{ email: '', password: '', age: '' },
{
validators: {
email: v.email('Invalid'),
password: v.minLength(8, 'Too short'),
age: v.min(18, 'Must be 18+')
}
}
);✅ You want concise, production code
// Cleaner and easier to scan
v.combine(v.required('Required'), v.email('Invalid'))✅ You're combining multiple validators
// Much cleaner with 'v'
v.combine(
v.required('Required'),
v.minLength(8, 'Too short'),
v.pattern(/[A-Z]/, 'Need uppercase')
)
// vs
Forms.validators.combine(
Forms.validators.required('Required'),
Forms.validators.minLength(8, 'Too short'),
Forms.validators.pattern(/[A-Z]/, 'Need uppercase')
)Common Patterns
Pattern 1: Destructure at Module Level
// At the top of your file
const { v } = Forms;
// Use throughout
export function createLoginForm() {
return Forms.create(
{ email: '', password: '' },
{
validators: {
email: v.combine(v.required('Required'), v.email('Invalid')),
password: v.combine(v.required('Required'), v.minLength(8, 'Too short'))
}
}
);
}
export function createSignupForm() {
return Forms.create(
{ username: '', email: '', password: '' },
{
validators: {
username: v.combine(v.required('Required'), v.minLength(3, 'Too short')),
email: v.combine(v.required('Required'), v.email('Invalid')),
password: v.combine(v.required('Required'), v.minLength(8, 'Too short'))
}
}
);
}Pattern 2: Create Custom Validator Library
const { v } = Forms;
// Build on top of built-in validators
export const myValidators = {
strongPassword: v.combine(
v.required('Password required'),
v.minLength(12, 'Min 12 characters'),
v.pattern(/[A-Z]/, 'Need uppercase'),
v.pattern(/[a-z]/, 'Need lowercase'),
v.pattern(/\d/, 'Need number'),
v.pattern(/[!@#$%^&*]/, 'Need special char')
),
validEmail: v.combine(
v.required('Email required'),
v.email('Invalid email format')
),
username: v.combine(
v.required('Username required'),
v.minLength(3, 'Min 3 characters'),
v.maxLength(20, 'Max 20 characters'),
v.pattern(/^[a-zA-Z0-9_]+$/, 'Letters, numbers, underscore only')
)
};Pattern 3: Inline Destructure (Function Scope)
function createForm() {
const { v } = Forms; // Destructure within function
return Forms.create(
{ email: '' },
{
validators: {
email: v.email('Invalid')
}
}
);
}Pattern 4: Consistent Team Style
Option A: Team prefers long form everywhere
// Team convention: Always use Forms.validators
const form1 = Forms.create({ email: '' }, {
validators: { email: Forms.validators.email() }
});
const form2 = Forms.create({ password: '' }, {
validators: { password: Forms.validators.minLength(8) }
});Option B: Team prefers short form everywhere
// Team convention: Always destructure and use 'v'
const { v } = Forms;
const form1 = Forms.create({ email: '' }, {
validators: { email: v.email() }
});
const form2 = Forms.create({ password: '' }, {
validators: { password: v.minLength(8) }
});Pick one convention and stick to it!
Summary
Key Takeaways
Forms.vis a shorthand alias forForms.validators- they're the exact same object.Use
Forms.vto save typing - especially when using multiple validators.Destructure with
const { v } = Formsfor the cleanest, most concise code.Both names access identical validators - there's no functional difference whatsoever.
Choose based on context - long form for clarity/teaching, short form for production.
Be consistent - don't mix both styles in the same file.
Character savings add up - using
vinstead ofvalidatorsreduces code by 35-58%.It's purely a convenience feature - use whichever you prefer!
One-Line Rule
Forms.vis a shorter way to writeForms.validators- use it to make your validation code more concise without changing functionality.
Quick Decision Guide
Choose Forms.validators if:
- Teaching/documenting ✅
- Maximum clarity needed ✅
- Only using 1-2 validators ✅
Choose Forms.v if:
- Multiple validators ✅
- Production code ✅
- Prefer concise style ✅
- Using
combine()✅
Destructure const { v } = Forms if:
- Using validators extensively ✅
- Want shortest possible code ✅
- Building validator libraries ✅
Remember: They're identical in functionality - the choice is purely stylistic!
What's Next?
- Explore all available validators in depth
- Learn form methods (
setValue,validate,submit) - Master validator composition with
combine() - Create custom reusable validators