
JustValidate is a dependency-free JavaScript form validation library that validates browser forms with built-in rules, custom validators, asynchronous checks, file rules, localized messages, and configurable error feedback.
The core package has zero runtime dependencies and works with regular HTML forms. Validation rules live in JavaScript through methods such as addField() and addRequiredGroup(), while manual revalidation, custom error placement, automatic submission, and an optional date plugin handle more advanced form workflows.
Features
- Zero runtime dependencies.
- Built-in text, email, number, password, regex, and file rules.
- Synchronous and asynchronous custom validators.
- Field, checkbox group, and radio group validation.
- Custom error and success messages.
- Custom CSS classes, inline styles, error containers, and tooltips.
- Manual field, group, and form revalidation.
- Conditional validation for dynamic form fields.
- Localized validation messages.
- Date validation through the JustValidatePluginDate package.
Use Cases
- Signup and account forms with password and email checks.
- Contact and lead forms with custom validation messages.
- File upload forms with type, extension, size, and file-count limits.
- Forms that need asynchronous server checks before submission.
How To Use It
Installation
Install JustValidate from npm or Yarn when your project uses a module bundler.
# npm npm install just-validate --save # Yarn yarn add just-validate
Import the package and create a validator for the target form.
import JustValidate from 'just-validate';
const validator = new JustValidate('#signup-form');Browser-only pages can load the production build from a CDN. The global constructor is available as window.JustValidate.
<script src="https://unpkg.com/just-validate@latest/dist/just-validate.production.min.js"></script>
<script>
const validator = new window.JustValidate('#signup-form');
</script>Basic Usage
Create a normal HTML form first. The field selectors used in JavaScript must match elements inside the form.
<form id="signup-form" novalidate> <label for="user-name">Name</label> <input id="user-name" name="name" type="text"> <label for="user-email">Email</label> <input id="user-email" name="email" type="email"> <label for="user-password">Password</label> <input id="user-password" name="password" type="password"> <button type="submit">Create Account</button> </form>
Define each field with addField(). Multiple rules run against the same field, and each rule can use its own error message.
const validator = new JustValidate('#signup-form');
validator
.addField('#user-name', [
{
rule: 'required',
errorMessage: 'Enter your name.',
},
{
rule: 'minLength',
value: 3,
errorMessage: 'Use at least 3 characters.',
},
])
.addField('#user-email', [
{
rule: 'required',
errorMessage: 'Enter your email address.',
},
{
rule: 'email',
errorMessage: 'Enter a valid email address.',
},
])
.addField('#user-password', [
{
rule: 'required',
},
{
rule: 'strongPassword',
errorMessage: 'Use a stronger password.',
},
]);Built-in Validation Rules
Combine required with other rules when an empty value must fail validation. Rules such as number, minLength, and maxNumber do not replace the required check.
| Rule | Description |
|---|---|
required | Checks that the field has a value. |
email | Checks for a valid email address. |
minLength | Checks the minimum text length. |
maxLength | Checks the maximum text length. |
number | Accepts integer or floating-point numbers. |
integer | Accepts integer numbers. |
minNumber | Checks the minimum numeric value. |
maxNumber | Checks the maximum numeric value. |
password | Checks the built-in password pattern. |
strongPassword | Checks the built-in stronger password pattern. |
customRegexp | Checks a value against a custom regular expression. |
minFilesCount | Checks the minimum number of selected files. |
maxFilesCount | Checks the maximum number of selected files. |
files | Checks selected file extensions, MIME types, sizes, or names. |
Custom Validation Rules
Set a validator function when the built-in rules do not match a project-specific requirement. A synchronous validator returns true or false.
validator.addField('#coupon-code', [
{
validator: (value) => /^[A-Z]{3}-\d{4}$/.test(value),
errorMessage: 'Use the format ABC-1234.',
},
]);Custom validators can also compare values from other registered fields. This pattern works well for password confirmation and dependent inputs.
validator.addField('#confirm-password', [
{
validator: (value, fields) => {
const passwordField = fields['#user-password'];
return passwordField ? value === passwordField.elem.value : true;
},
errorMessage: 'Passwords must match.',
},
]);Async Validation
An asynchronous custom validator returns a function that returns a Promise<boolean>. This fits username, email, coupon, or account checks that depend on a backend response.
async function checkEmailAvailability(email) {
const response = await fetch(
`/api/email-available?email=${encodeURIComponent(email)}`
);
const result = await response.json();
return result.available;
}
validator.addField('#user-email', [
{
rule: 'required',
},
{
rule: 'email',
},
{
validator: (value) => () => checkEmailAvailability(value),
errorMessage: 'This email address is already registered.',
},
]);File Validation
Use minFilesCount and maxFilesCount for the number of selected files. The files rule checks extensions, MIME types, file names, and file size in bytes.
validator.addField('#attachments', [
{
rule: 'minFilesCount',
value: 1,
},
{
rule: 'maxFilesCount',
value: 3,
},
{
rule: 'files',
value: {
files: {
extensions: ['jpg', 'jpeg', 'png'],
types: ['image/jpeg', 'image/png'],
minSize: 10000,
maxSize: 2500000,
},
},
},
]);Date Validation
Date checks live in the separate just-validate-plugin-date package. Install the plugin when the form needs date formats or before/after comparisons.
npm install just-validate-plugin-date
Import JustValidatePluginDate and attach it to a field rule. Text inputs can define a format such as dd/MM/yyyy.
import JustValidatePluginDate from 'just-validate-plugin-date';
validator.addField('#start-date', [
{
rule: 'required',
},
{
plugin: JustValidatePluginDate(() => ({
format: 'dd/MM/yyyy',
})),
errorMessage: 'Use the DD/MM/YYYY date format.',
},
]);Manual Validation And Revalidation
JustValidate exposes manual revalidation for the entire form, one field, or one required group. Each revalidation method returns a promise that resolves to a boolean validation result.
// Validate the entire form.
validator.revalidate().then((isValid) => {
console.log(isValid);
});
// Validate one field.
validator.revalidateField('#user-email').then((isValid) => {
console.log(isValid);
});
// Validate a checkbox or radio group.
validator.revalidateGroup('#contact-methods').then((isValid) => {
console.log(isValid);
});Required Checkbox And Radio Groups
Use addRequiredGroup() when at least one checkbox or radio option in a container must be selected.
<div id="contact-methods"> <label><input type="radio" name="contact" value="email"> Email</label> <label><input type="radio" name="contact" value="sms"> SMS</label> </div>
validator.addRequiredGroup( '#contact-methods', 'Select a preferred contact method.' );
Form Submission
The default validation flow does not submit the form automatically. Use onSuccess() for custom submission logic or set submitFormAutomatically to true for a normal browser form submission after successful validation.
const validator = new JustValidate('#signup-form', {
submitFormAutomatically: true,
});Custom submit logic can run inside onSuccess(). The callback receives the form submit event.
validator.onSuccess((event) => {
const form = event.currentTarget;
const formData = new FormData(form);
fetch(form.action, {
method: form.method || 'POST',
body: formData,
});
});Styling Errors And Success States
Global configuration accepts custom classes and styles for invalid fields, valid fields, error labels, and success labels. CSS classes keep presentation rules in your stylesheet.
const validator = new JustValidate('#profile-form', {
errorFieldCssClass: 'field-invalid',
errorLabelCssClass: 'field-error-message',
successFieldCssClass: 'field-valid',
successLabelCssClass: 'field-success-message',
focusInvalidField: true,
});Define the matching classes in your own stylesheet.
.field-invalid {
border-color: #c62828;
}
.field-error-message {
color: #c62828;
font-size: 0.875rem;
}
.field-valid {
border-color: #2e7d32;
}
.field-success-message {
color: #2e7d32;
font-size: 0.875rem;
}Custom Error Containers And Tooltips
Set errorsContainer when validation messages belong in a dedicated element. Set tooltip.position to display error labels as tooltips on the left, top, right, or bottom.
const validator = new JustValidate('#checkout-form', {
errorsContainer: '#validation-summary',
tooltip: {
position: 'top',
},
});Localization
Pass a locale dictionary as the third constructor argument. Each dictionary key must match the corresponding errorMessage, and setCurrentLocale() switches the active translation.
const validator = new JustValidate(
'#contact-form',
undefined,
[
{
key: 'Email is required',
dict: {
es: 'El correo electrónico es obligatorio',
fr: "L’adresse e-mail est obligatoire",
},
},
]
);
validator.addField('#email', [
{
rule: 'required',
errorMessage: 'Email is required',
},
]);
validator.setCurrentLocale('es');Configuration Options
Pass global configuration as the second argument to new JustValidate(form, globalConfig, dictLocale). Field-level configuration in addField() can override the relevant global styling and error-placement settings.
errorFieldStyle(Partial<CSSStyleDeclaration>): Inline styles applied to invalid fields.errorFieldCssClass(string | string[]): CSS class or classes applied to invalid fields.errorLabelStyle(Partial<CSSStyleDeclaration>): Inline styles applied to error labels.errorLabelCssClass(string | string[]): CSS class or classes applied to error labels.successFieldStyle(Partial<CSSStyleDeclaration>): Inline styles applied to valid fields.successFieldCssClass(string | string[]): CSS class or classes applied to valid fields.successLabelStyle(Partial<CSSStyleDeclaration>): Inline styles applied to success labels.successLabelCssClass(string | string[]): CSS class or classes applied to success labels.focusInvalidField(boolean): Focuses the first invalid field after form submission when enabled.lockForm(boolean): Locks form controls while validation runs.tooltip(object): Displays error labels as tooltips.positionacceptsleft,top,right, orbottom.errorsContainer(string | Element): Places error labels inside a specified container.validateBeforeSubmitting(boolean): Runs validation and displays field errors before form submission.submitFormAutomatically(boolean): Submits the form after successful validation.testingMode(boolean): Addsdata-testidattributes to generated validation elements.
API Methods
// Define validation rules for a field.
validator.addField('#email', rules, fieldConfig);
// Make a checkbox or radio group required.
validator.addRequiredGroup('#contact-methods', errorMessage, fieldConfig);
// Run after a successful form validation.
validator.onSuccess((event) => {
// ...
});
// Run after a failed form validation.
validator.onFail((fields, groups) => {
// ...
});
// Run after each validation pass.
validator.onValidate((state) => {
console.log(state.isValid, state.isSubmitted);
});
// Revalidate a single field.
validator.revalidateField('#email').then((isValid) => {});
// Revalidate a required group.
validator.revalidateGroup('#contact-methods').then((isValid) => {});
// Revalidate the entire form.
validator.revalidate().then((isValid) => {});
// Remove a field from validation.
validator.removeField('#company');
// Remove a required group from validation.
validator.removeGroup('#contact-methods');
// Display an error message manually.
validator.showErrors({ '#email': 'This email is unavailable.' });
// Display a success message manually.
validator.showSuccessLabels({ '#email': 'Email is available.' });
// Switch the active locale.
validator.setCurrentLocale('es');
// Rebuild field settings and clear current validation output.
validator.refresh();
// Remove validation listeners, messages, styles, and classes.
validator.destroy();Implementation Tips
- Register fields that belong to the form passed to the constructor.
- Pair
requiredwith format, length, and numeric rules when empty values must fail. - Use
removeField()andremoveGroup()when conditional controls leave the active form flow. - Use
lockFormfor asynchronous checks that should block input during validation. - Use
validateBeforeSubmittingwhenonValidate()needs a complete form validity state before submit. - Keep date logic in
JustValidatePluginDateinstead of treating date checks as a core built-in rule.
How It Works
JustValidate registers rules against fields inside one form instance and listens for the appropriate input or change events. Each validation pass updates the field state, renders configured error or success feedback, and exposes the current result to callbacks and manual revalidation methods.
Custom validators use the same field pipeline as built-in rules. Synchronous validators return a boolean value. Asynchronous validators return a function that resolves a promise with the validation result.
Alternatives And Related Resources
- 10 Best Pure JavaScript Form Validation Libraries
- Vanilla JavaScript Form Validation with Custom Rules and Messages – js-validation
- Native HTML Form Validation Enhancer with Zod Support – validation-enhancer
- Feature-rich Form Validation Library – OctaValidate
FAQs
Q: Does JustValidate require jQuery?
A: No. The core package has zero runtime dependencies and works with browser forms through JavaScript.
Q: Can JustValidate be loaded from a CDN?
A: Yes. Load the production build from unpkg and create the instance with window.JustValidate.
Q: Why does revalidate() return a promise?
A: Manual revalidation supports asynchronous validation rules. revalidate(), revalidateField(), and revalidateGroup() resolve to boolean results after validation finishes.
Q: Why is an empty field passing number or length validation?
A: Define the required rule when empty input must fail. Other rules check their own constraint and do not replace the required check.
Q: How do I validate dates with JustValidate?
A: Install just-validate-plugin-date and use JustValidatePluginDate in the field rules. The plugin handles formats and before/after date comparisons.
Changelog
v4.3.0 (11/13/2023)
- Added the
submitFormAutomaticallysetting.
v4.2.0 (02/07/2023)
- Added the
onValidatecallback.
v4.1.0 (02/01/2023)
- Added the
revalidateGroupmethod.
v4.0.0 (12/29/2022)
- Added the
integerrule. - Changed empty-field handling for email validation.
v3.9.0 (12/08/2022)
- Added the
validateBeforeSubmittingsetting.
v3.5.0 (02/15/2022)
- Added manual form and field revalidation methods.
v3.2.0 (12/30/2021)
- Added plugin support and date validation through the date plugin.
v3.1.0 (12/27/2021)
- Added file count and file attribute validation rules.
v3.0.0 (12/27/2021)
- Changed required-field behavior for non-required validation rules.
v2.0.0 (12/07/2021)
- Introduced the main field, group, localization, callback, and error-rendering APIs used by the modern library.








ia have two file to uploade, how can i upload them?
many thanks