A high-performance Laravel-inspired validation library for TypeScript/JavaScript
- 🚀 Laravel-Style Validation: Define rules using a fluent API or Laravel-style strings
- 🔒 Type-Safe: Built with TypeScript for robust type checking and inference
- 🌐 Frontend-Focused: Designed for browser environments with support for file validation
- 🎨 Customizable: Add custom rules, error messages, and localization
- ⚡ Framework-Agnostic: Works with vanilla JavaScript, React, Vue, Node.js, and more
- 🔄 Async Support: Validate data asynchronously for complex use cases
- 📱 Cross-Platform: Browser, Node.js, and mobile app support
- 🎯 High Performance: Optimized for speed with minimal bundle size
Install ValidlyJS via npm:
npm install validlyjs
Or via yarn:
yarn add validlyjs
import { Validator, string, number } from 'validlyjs';
const validator = new Validator({
name: string().required().min(3),
age: number().min(18).max(120),
email: string().email().required()
});
const data = {
name: "John",
age: 25,
email: "john@example.com"
};
const result = await validator.validate(data);
if (!result.isValid) {
console.log("Validation Errors:", result.errors);
} else {
console.log("Data is valid!");
}
import { Validator } from 'validlyjs';
const validator = new Validator({
username: "required|min:3|max:20|alpha",
email: "required|email",
password: "required|min:8|confirmed"
});
const result = await validator.validate({
username: "john_doe",
email: "john@example.com",
password: "secretpassword",
password_confirmation: "secretpassword"
});
const validator = new Validator({
password: ["required", "min:8", "max:20"],
tags: ["array", "min:1", "max:5"]
});
import { string } from 'validlyjs';
const schema = {
username: string()
.required()
.min(3)
.max(20)
.alpha()
.lowercase(),
email: string()
.required()
.email()
.max(255),
url: string()
.url()
.nullable(),
phone: string()
.regex(/^\+?[1-9]\d{1,14}$/)
};
import { number } from 'validlyjs';
const schema = {
age: number()
.required()
.min(18)
.max(120)
.integer(),
price: number()
.required()
.min(0)
.decimal(2),
rating: number()
.between(1, 5)
};
import { array, object, string, number } from 'validlyjs';
const schema = {
tags: array()
.required()
.min(1)
.max(5)
.unique(),
user: object()
.required()
.shape({
name: string().required(),
age: number().min(18),
preferences: object().shape({
theme: string().in(['light', 'dark']),
notifications: boolean()
})
})
};
import { date } from 'validlyjs';
const schema = {
birthDate: date()
.required()
.before('today')
.after('1900-01-01'),
appointmentDate: date()
.required()
.after('today')
.format('YYYY-MM-DD')
};
import { file } from 'validlyjs';
const schema = {
avatar: file()
.required()
.maxSize('2MB')
.mimes(['jpg', 'png', 'gif'])
.dimensions('min_width=100,min_height=100'),
document: file()
.mimes(['pdf', 'doc', 'docx'])
.maxSize('10MB')
};
const validator = new Validator({
username: string()
.required()
.min(3)
.async(async (value) => {
const isAvailable = await checkUsernameAvailability(value);
return isAvailable ? true : "Username is already taken";
}),
email: string()
.required()
.email()
.async(async (value) => {
const exists = await checkEmailExists(value);
return !exists ? true : "Email is already registered";
})
});
const result = await validator.validateAsync({
username: "john_doe",
email: "john@example.com"
});
const validator = new Validator({
// Required if another field has a specific value
phone: string().requiredIf('contact_method', 'phone'),
// Required unless another field has a specific value
email: string().requiredUnless('contact_method', 'phone'),
// Required with other fields
city: string().requiredWith(['state', 'country']),
// Prohibited if another field has a specific value
discount: number().prohibitedIf('user_type', 'premium'),
// Conditional validation with when()
items: array().required().min(1),
'items.*': string().when('items', {
length: { gte: 5 },
then: string().min(10),
otherwise: string().min(3)
})
});
import { useValidator, string, number } from 'validlyjs/react';
function UserForm() {
const { validate, errors, isValid } = useValidator({
name: string().required().min(2),
email: string().required().email(),
age: number().required().min(18)
});
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const data = Object.fromEntries(formData);
const result = await validate(data);
if (result.isValid) {
// Submit form
console.log('Form is valid!', data);
}
};
return (
<form onSubmit={handleSubmit}>
<input name="name" placeholder="Name" />
{errors.name && <div className="error">{errors.name[0]}</div>}
<input name="email" type="email" placeholder="Email" />
{errors.email && <div className="error">{errors.email[0]}</div>}
<input name="age" type="number" placeholder="Age" />
{errors.age && <div className="error">{errors.age[0]}</div>}
<button type="submit" disabled={!isValid}>Submit</button>
</form>
);
}
<template>
<form @submit.prevent="handleSubmit">
<input v-model="form.name" placeholder="Name" />
<span v-if="errors.name" class="error">{{ errors.name[0] }}</span>
<input v-model="form.email" type="email" placeholder="Email" />
<span v-if="errors.email" class="error">{{ errors.email[0] }}</span>
<button type="submit" :disabled="!isValid">Submit</button>
</form>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useValidator, string } from 'validlyjs/vue';
const form = ref({
name: '',
email: '',
});
const { validate, errors, isValid } = useValidator({
name: string().required().min(2),
email: string().required().email(),
}, form);
const handleSubmit = async () => {
const result = await validate(form.value);
if (result.isValid) {
console.log('Form is valid!', form.value);
}
};
</script>
import express from 'express';
import { Validator, string, number } from 'validlyjs/node';
const app = express();
app.post('/users', async (req, res) => {
const validator = new Validator({
name: string().required().min(2),
email: string().required().email(),
age: number().required().min(18)
});
const result = await validator.validate(req.body);
if (!result.isValid) {
return res.status(422).json({
message: 'Validation failed',
errors: result.errors
});
}
// Process valid data
res.json({ message: 'User created successfully' });
});
import { Validator, string, extend } from 'validlyjs';
// Define a custom rule
extend(
"strong_password",
(value) => {
return /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/.test(value);
},
"The :attribute must contain at least one uppercase letter, one lowercase letter, one number, and one special character."
);
// Use the custom rule
const validator = new Validator({
password: string().required().custom("strong_password")
});
import { configure } from 'validlyjs';
configure({
messages: {
required: 'The :attribute field is required',
email: 'Please enter a valid email address',
min: {
string: 'The :attribute must be at least :min characters',
numeric: 'The :attribute must be at least :min'
}
}
});
import { configure } from 'validlyjs';
configure({
locale: 'es',
messages: {
required: 'El campo :attribute es obligatorio',
email: 'El campo :attribute debe ser un email válido',
min: {
string: 'El campo :attribute debe tener al menos :min caracteres'
}
}
});
ValidlyJS is optimized for performance:
- Tree-shakable: Import only what you need
- Fast validation: Optimized validation algorithms
- Memory efficient: Minimal memory footprint
- Async-friendly: Non-blocking validation
Run the test suite:
npm test
Run tests with coverage:
npm run test:coverage
Run integration tests:
npm run test:integrations
For comprehensive documentation, examples, and API reference, visit:
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Clone your fork:
git clone https://github.com/tobyemmanuel/validlyjs.git
- Install dependencies:
npm install
- Create a feature branch:
git checkout -b feature/your-feature
- Make your changes and add tests
- Run tests:
npm test
- Commit your changes:
git commit -m 'Add some feature'
- Push to the branch:
git push origin feature/your-feature
- Open a pull request
See CHANGELOG.md for a detailed list of changes.
ValidlyJS is open-source software licensed under the MIT License.
- Inspired by Laravel's validation system
- Built with ❤️ for the JavaScript/TypeScript community