Want to take your software engineering career to the next level? Join the mailing list for career tips & advice Click here


Object schema validation

Subscribe to updates I use joi

Statistics on joi

Number of watchers on Github 7356
Number of open issues 95
Average time to close an issue 4 days
Main language JavaScript
Average time to merge a PR 5 days
Open pull requests 37+
Closed pull requests 58+
Last commit over 2 years ago
Repo Created almost 8 years ago
Repo Last Updated over 2 years ago
Size 3.18 MB
Organization / Authorhapijs
Page Updated
Do you use joi? Leave a review!
View open issues (95)
View joi activity
View on github
Fresh, new opensource launches 🚀🚀🚀
Software engineers: It's time to get promoted. Starting NOW! Subscribe to my mailing list and I will equip you with tools, tips and actionable advice to grow in your career.
Evaluating joi for your project? Score Explanation
Commits Score (?)
Issues & PR Score (?)

joi Logo

Object schema description language and validator for JavaScript objects.

npm version Build Status NSP Status Known Vulnerabilities

Lead Maintainer: Nicolas Morel


Imagine you run facebook and you want visitors to sign up on the website with real names and not something like l337_p@nda in the first name field. How would you define the limitations of what can be inputted and validate it against the set rules?

This is joi, joi allows you to create blueprints or schemas for JavaScript objects (an object that stores information) to ensure validation of key information.


See the detailed API Reference.


const Joi = require('joi');

const schema = Joi.object().keys({
    username: Joi.string().alphanum().min(3).max(30).required(),
    password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
    access_token: [Joi.string(), Joi.number()],
    birthyear: Joi.number().integer().min(1900).max(2013),
    email: Joi.string().email()
}).with('username', 'birthyear').without('password', 'access_token');

// Return result.
const result = Joi.validate({ username: 'abc', birthyear: 1994 }, schema);
// result.error === null -> valid

// You can also pass a callback which will be called synchronously with the validation result.
Joi.validate({ username: 'abc', birthyear: 1994 }, schema, function (err, value) { });  // err === null -> valid

The above schema defines the following constraints:

  • username
    • a required string
    • must contain only alphanumeric characters
    • at least 3 characters long but no more than 30
    • must be accompanied by birthyear
  • password
    • an optional string
    • must satisfy the custom regex
    • cannot appear together with access_token
  • access_token
    • an optional, unconstrained string or number
  • birthyear
    • an integer between 1900 and 2013
  • email
    • a valid email address string


Usage is a two steps process. First, a schema is constructed using the provided types and constraints:

const schema = {
    a: Joi.string()

Note that joi schema objects are immutable which means every additional rule added (e.g. .min(5)) will return a new schema object.

Then the value is validated against the schema:

const {error, value} = Joi.validate({ a: 'a string' }, schema);

// or

Joi.validate({ a: 'a string' }, schema, function (err, value) { });

If the input is valid, then the error will be null, otherwise it will be an Error object.

The schema can be a plain JavaScript object where every key is assigned a joi type, or it can be a joi type directly:

const schema = Joi.string().min(10);

If the schema is a joi type, the schema.validate(value, callback) can be called directly on the type. When passing a non-type schema object, the module converts it internally to an object() type equivalent to:

const schema = Joi.object().keys({
    a: Joi.string()

When validating a schema:

  • Values (or keys in case of objects) are optional by default.

    Joi.validate(undefined, Joi.string()); // validates fine

    To disallow this behavior, you can either set the schema as required(), or set presence to "required" when passing options:

    Joi.validate(undefined, Joi.string().required());
    // or
    Joi.validate(undefined, Joi.string(), /* options */ { presence: "required" });
  • Strings are utf-8 encoded by default.

  • Rules are defined in an additive fashion and evaluated in order after whitelist and blacklist checks.


Joi doesn't directly support browsers, but you could use joi-browser for an ES5 build of Joi that works in browsers, or as a source of inspiration for your own builds.


This project is kindly sponsored by:

nearForm logo

joi open issues Ask a question     (View All Issues)
  • over 3 years Concatenating schema give strange results
  • over 3 years Use "when" inside "when" in Joi
  • over 3 years Joi.string().invalid (not, disallow) doesn't support regex?
  • over 3 years Array length cannot reference to another field
  • over 3 years Suggestion: Joi.string().uri({ allowRelativeOnly })
  • over 3 years Equivalent of strip() if error occurs ?
  • over 3 years Request: Warn when functions are passed unexpected arguments
  • over 3 years Request for documentation for error -> details -> context
  • over 3 years Joi validating string as array
  • over 3 years Correct way to write an "identity" extension?
  • over 3 years Where is the documentation for `this.createError()`?
  • almost 4 years Trying to rename key to nested object key
  • almost 4 years Unexpected interaction between Joi.object().unknown() and stripUnknown
  • almost 4 years Required array does not have required property set
  • almost 4 years Access annotations in error details (e.g. in context)
  • almost 4 years Determine parts of object only valid when validated with 'allowUnknown: true'?
  • almost 4 years Joi wrong value parsing
  • almost 4 years Question: How to require a filed only if another field is present?
  • almost 4 years date and timezone issue
  • almost 4 years Custom error message how to display the {{value}} they entered?
  • almost 4 years Feature Request: generate valid example from schema
  • about 4 years Support for ES6 Types
  • about 4 years One error cause per wrong field
  • about 4 years Email validation doesn't allow emails which are compliant with RFC 6530
  • about 4 years Validating a FQDN
  • about 4 years $-sign in object keys are escaped in the ValidationError message
  • about 4 years Reference should apply defaults
  • about 4 years Language: "message prefix"
  • about 4 years String to Object Conversion With Regexes
  • about 4 years Maybe array().unique() with convert: true should remove duplicates?
joi open pull requests (View All Pulls)
  • Update license year to 2016
  • add support for arrays to the alternatives.when() method in order to val...
  • code and tests for .withor
  • Add the ability to specify a comparator for `array.unique()` for objects only
  • Allow 1 to be true and 0 to be false.
  • Wwarren 833 truncate
  • id-833: Proposal string().truncate()
  • initial undescribe functionality
  • Proposal: Add support for global refs
  • number.multiple() enhancement - Issue #916
  • Protective check for error flag
  • Alias String.guid() with String.uuid()
  • Add support for truthy/falsy boolean values
  • Change Joi.validate examples to just return a value
  • Improve slightly any() documentation
  • Convert/Cast to string if value is a number
  • Added support for ISO_8601 expansion (+/-YYYYYY)
  • Fix #1156 - Adds support for optional base64 padding validation.
  • Fix #1167 - make err.context.key the original key, add err.context.label
  • Alternatives respect subsequent "when"s if first has only "otherwise"
  • Add "options" to describe output
  • Passes the "default" function to the schema description
  • Make isemail an optional dependency
  • Remove confusing paragraph for string modifiers
  • Allow passing an option to string().isoDate()
  • undefined in the array with label returns "correct missing value" message
  • Use isJoi and _currentJoi.version to determine schema compatiblity
  • Add host validation to Strings
  • Added a separator parameter for Joi.reach
  • Avoid redundant copies of settings
  • Add byteAligned option to hex string
  • Fixes : Validate port numbers #1346
  • Use Set() for internal Set backend
  • Update API Reference.
  • Use Set() for handling of unprocessed keys
  • Add an object.append() method. Fixes #1381.
  • Changed a separator for path parameter to pre-split array approach for Joi.reach
joi questions on Stackoverflow (View All Questions)
  • Best way to maintain only one schema between Mongoose and Joi
  • Hapi/Joi validation with nested object
  • How to access key outside of array in when condition of JOI schema validation
  • Generating Joi validation a Sequelize model
  • Loading Joi Schemas From Files
  • ArangoDb Foxx joi validate unknown keys
  • Joi validation schema - two fields must not have the same value
  • How to properly share Hapi Joi validation schemas between models without circular dependency
  • Joi Validation - Compare to dates from POST
  • hapijs joi email validation option tldWhitelist usage
  • How to create browse button using hapi-swagger and joi in node
  • Allow optional parameters in Joi without specifying them
  • Using Joi, validating that a boolean is true
  • One route, two valid payloads in Hapi.js with Joi
  • How to avoid Hapi.js sending 400 error when Validating Request with Joi
  • Striping unknown keys when validating with Joi
  • hapi joi how to validate Optional parameters
  • node hapi rest put update joi validate only if present
  • How to specify HTTP error 422 instead of 400 in Hapi Joi
  • Ignoring "required" in Joi validation?
  • Validate REST parameters using Joi in Nodejs
  • How to split field values with Hapi.js using Joi
  • Validating array items with joi in a Foxx app
  • how to return a validation property on a hapi reply like the way Joi library does it
  • When using Joi with Hapi, how does one setup a require on one key but allow any and all other keys?
  • Using Joi, how to use .or for recursive objects
  • Using Joi/Hapi, how can one validate the entries in a hash, for all keys?
  • hapi joi filter valid value
  • hapi route joi validation of password confirmation
  • How to capture callback from failed validation in Joi
joi list of languages used
Other projects in JavaScript