Object schema validation
Joi is a mature schema validation library designed for Node.js applications that need robust data validation. With over 15 million weekly downloads, it's the go-to solution for validating incoming API requests, configuration objects, form data, and any JavaScript objects against defined schemas. The library uses a chainable, declarative API that makes validation rules readable and maintainable.
Originally developed as part of the hapi.js ecosystem, Joi has evolved into a standalone validation powerhouse used across the Node.js ecosystem. It excels at expressing complex validation logic including conditional rules, custom validators, type coercion, and detailed error reporting. The library handles all primitive types plus nested objects, arrays, dates, and binary data with extensive built-in validators.
Joi is particularly valuable in backend environments where validation requirements grow complex over time. Unlike simpler validation libraries, it provides deep customization through methods like .when() for conditional logic, .custom() for bespoke validation functions, and .transform() for data manipulation during validation. The library is synchronous by default but supports async validation, making it suitable for scenarios requiring database lookups or external API calls during validation.
Development teams choose Joi when they need production-grade validation that can handle edge cases, provide clear error messages, and scale with application complexity. Its BSD-3-Clause license and active maintenance make it a safe choice for commercial projects requiring reliable data integrity enforcement.
const Joi = require('joi');
// Define schema for user registration
const userSchema = Joi.object({
username: Joi.string()
.alphanum()
.min(3)
.max(30)
.required(),
email: Joi.string()
.email()
.required(),
password: Joi.string()
.pattern(new RegExp('^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{8,}$'))
.required()
.messages({
'string.pattern.base': 'Password must contain uppercase, lowercase, and number'
}),
age: Joi.number()
.integer()
.min(18)
.max(120)
.optional(),
role: Joi.string()
.valid('user', 'admin', 'moderator')
.default('user'),
// Conditional validation: require creditCards only if hasPremium is true
hasPremium: Joi.boolean(),
creditCards: Joi.array()
.items(Joi.string().creditCard())
.when('hasPremium', {
is: true,
then: Joi.required(),
otherwise: Joi.forbidden()
})
});
// Validate data
const userData = {
username: 'john_doe',
email: 'john@example.com',
password: 'SecurePass123',
age: 25,
hasPremium: true,
creditCards: ['4111111111111111']
};
const { error, value } = userSchema.validate(userData, {
abortEarly: false, // Return all errors, not just first
stripUnknown: true // Remove fields not in schema
});
if (error) {
console.log('Validation errors:', error.details.map(d => ({
field: d.path.join('.'),
message: d.message
})));
} else {
console.log('Valid data:', value);
}API Request Validation: Express, Fastify, and hapi applications use Joi middleware to validate request bodies, query parameters, and headers before reaching business logic. The library catches malformed data early, preventing invalid data from propagating through the application stack and providing structured error responses to API consumers.
Configuration File Validation: Applications loading environment variables or configuration files validate settings against Joi schemas to ensure all required fields exist, types are correct, and values fall within acceptable ranges. This catches configuration errors at startup rather than during runtime.
Form Data Sanitization: Backend services receiving user registration, profile updates, or complex multi-step form submissions use Joi to validate fields with rules like password strength requirements, email format verification, age restrictions, and cross-field dependencies (e.g., requiring billing address only when payment method is credit card).
Data Pipeline Validation: ETL processes, data import systems, and message queue consumers validate incoming data batches against schemas to filter out corrupt records, transform data to expected formats, and generate detailed validation reports for data quality monitoring.
Database Input Validation: Before inserting or updating database records, applications validate data structures to ensure referential integrity, enforce business rules not covered by database constraints, and prevent injection attacks through strict type and format validation.
npm install joipnpm add joibun add joi