Joi - The best data validator for JavaScript

Updated on Apr 15, 2021β€’toolsjavascript

Type safety in JavaScript is weak (implicit type conversion) and dynamic (type checking happens at runtime). This is a feature that both makes JavaScript popular (short syntax, fast prototyping, etc) and also causes tons of stupid hard-to-debug production errors.

Dynamic type checking may cause a program to fail at runtime, type-checking errors are considered fatal, and this is the last thing you want to happen in live products.

Most static type checkers like Flow or TypeScript don’t guarantee type safety at runtime because all their type annotations will be stripped away at compile time.

You desperately need data validation at runtime in JavaScript applications that handle arbitrary user inputs, parse JSON content from HTTP requests, marshal and unmarshal data objects for storage or transmit through networks.

Instead of having your data validation and sanitization logic written as lengthy code, you can declare the requirements to your data with concise, easy to read and cross-platform schema description language and validate the data as soon as it arrives to your application.

Joi is the most powerful schema description language and data validator for JavaScript, for Node.js and browser. It lets you describe your data using a simple, intuitive, and readable language.

// https://joi.dev/api/?v=17.4.0

const Joi = require('joi')

const schema = Joi.object({
  username: Joi.string().alphanum().min(3).max(30).required(),

  password: Joi.string().pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')),

  repeat_password: Joi.ref('password'),

  access_token: [Joi.string(), Joi.number()],

  birth_year: Joi.number().integer().min(1900).max(2013),

  email: Joi.string().email({
    minDomainSegments: 2,
    tlds: {allow: ['com', 'net']}
  })
})
  .with('username', 'birth_year')
  .xor('password', 'access_token')
  .with('password', 'repeat_password')

schema.validate({username: 'abc', birth_year: 1994})
// -> { value: { username: 'abc', birth_year: 1994 } }

schema.validate({})
// -> { value: {}, error: '"username" is required' }

There are other less popular JavaScript data validators allow you define a schema, transform a value to match, validate the shape of an existing value, or both.

  • Yup - Heavily inspired by Joi but leaner and built with client-side validation as its primary use-case. Yup always relies on the Promise global object to handle asynchronous values as well as Set and Map.
  • Ajv - The fastest JSON validator for Node.js and browser, including the latest draft 2020-12.
  • Superstruct - Its type annotation API was inspired by Typescript, Flow, Go, and GraphQL, giving it a familiar and easy to understand API.

Check out comprehensive alternatives to Joi here.