Guide · Open source
How to use class-validator: decorators, validate and errors
Updated · written with AI from the project's own documentation and checked against our catalogue data
class-validator is a TypeScript and JavaScript library that lets you attach validation rules to the properties of a class using decorators, then check an object against those rules. It works in Node.js and in the browser. This guide shows you how to install it, define a validated class, call validate, read the errors it returns, and customise messages.
Quick start
- 1Check your environment. Confirm you have Node.js and npm 6 or later installed.
- 2Install the package. Run npm install class-validator --save in your project folder.
- 3Create a class. Write a class and add decorators such as @Length, @IsEmail or @Min to the properties you want to check.
- 4Assign values. Create an instance of the class and set the property values you want to test.
- 5Call validate. Pass the instance to validate and wait for the returned promise.
- 6Handle the errors. Check whether the returned array is empty, and show or send the ValidationError objects if it is not.
Install class-validator with npm
Install the package with npm. The README asks for npm 6 or later, because from npm@6 the dependency tree is flattened, which class-validator needs to function properly.
- Prerequisites: Node.js and npm 6 or later
- Install the package into your project
npm install class-validator --saveDefine a class with validation decorators
Create a class and put decorators on the properties you want to check. Each decorator states one rule, such as a length range, a substring, an integer, an email address, a fully qualified domain name, a date, or a minimum and maximum number. Several decorators can be stacked on the same property.
- @Length(10, 20) checks string length
- @Contains('hello') checks that a string contains a value
- @IsInt(), @Min(0) and @Max(10) check a number
- @IsEmail() and @IsFQDN() check string formats
- @IsDate() checks that a value is a date
import { Length, Contains, IsInt, Min, Max, IsEmail, IsFQDN, IsDate } from 'class-validator';
export class Post {
@Length(10, 20)
title: string;
@Contains('hello')
text: string;
@IsInt()
@Min(0)
@Max(10)
rating: number;
@IsEmail()
email: string;
@IsFQDN()
site: string;
@IsDate()
createDate: Date;
}Run validate and read the results
Create an instance, assign values, and pass it to validate. The function returns a promise that resolves to an array of ValidationError objects. An empty array means every rule passed. Each error includes the target object, the property name, the value that failed, and a constraints object with a message for each failed rule.
If you prefer exceptions, validateOrReject rejects the promise when validation fails, so you can handle errors in a try and catch block.
- target: the object that was validated
- property: the field that failed
- value: the value that failed
- constraints: failed rule names mapped to messages
- children: nested errors for the property
import { validate, validateOrReject } from 'class-validator';
validate(post).then(errors => {
if (errors.length > 0) {
console.log('validation failed. errors: ', errors);
} else {
console.log('validation succeed');
}
});
async function validateOrRejectExample(input) {
try {
await validateOrReject(input);
} catch (errors) {
console.log('Caught promise rejection (validation failed). Errors: ', errors);
}
}Customise error messages and hide the target
You can pass a message in the decorator options. You can also use tokens such as $property, $value, $target and $constraint1 inside the message, or pass a function that receives ValidationArguments and returns a message.
When you send errors back over HTTP, you usually do not want to expose the whole target object. Passing validationError with target set to false removes it from the output.
- Tokens: $value, $property, $target, $constraint1 to $constraintN
- Message function receives value, constraints, targetName, object and property
- Validation options include skipMissingProperties, whitelist, forbidNonWhitelisted, groups, stopAtFirstError and forbidUnknownValues
import { MinLength, MaxLength } from 'class-validator';
export class Post {
@MinLength(10, {
message: 'Title is too short. Minimal length is $constraint1 characters, but actual is $value',
})
@MaxLength(50, {
message: 'Title is too long. Maximal length is $constraint1 characters, but actual is $value',
})
title: string;
}
validator.validate(post, { validationError: { target: false } });Validate arrays, sets, maps and nested objects
For arrays, sets and maps, add the each: true option so the rule runs on every item rather than the collection itself. The README also covers nested objects, promises and inherited decorators, which are useful once your models grow.
- Arrays and sets: each: true validates every item
- Maps: each: true validates every item in the map
- Nested objects and promises have their own sections in the README
import { MaxLength } from 'class-validator';
export class Post {
@MaxLength(20, {
each: true,
})
tags: string[];
}Use non-decorator schemas when decorators do not fit
The README says class-validator also supports defining a validation schema without decorators, and validating plain objects. The excerpt used for this guide does not show how this works in detail, so check the README section of that name before relying on it.
The library uses validator.js internally to perform the checks. Note that forbidUnknownValues is true by default, and the README advises keeping that default, because setting it to false lets unknown objects pass validation.
- Decorator-based validation is the main approach shown in the README
- Non-decorator schemas are documented in a separate README section
What people use it for
- Checking a request body in a Node.js API before saving it
- Returning structured validation errors to an API client
- Validating form data with the same class rules in the browser
- Checking that a string is an email address or a valid domain name
- Validating each item in an array of tags with each: true
Frequently asked questions
How do I install class-validator?
Run npm install class-validator --save in your project. The README asks for npm 6 or later, because the flattened dependency tree is needed for the library to work properly.
Does class-validator work in the browser?
Yes. The README states that class-validator works on both browser and node.js platforms.
What license is class-validator under?
class-validator is released under the MIT licence, as listed in the project details for this directory entry.
Do I need TypeScript to use class-validator?
The main API depends on decorators, and the examples are written in TypeScript. The README also offers a non-decorator option, but the excerpt used for this guide covers it only briefly, so check the full README for details.
Why does validate return an empty array?
An empty array means no rule failed. If validate returns errors, each ValidationError lists the property, the value that failed and the constraint messages.
How does class-validator compare with Joi, Zod, Yup or Ajv?
The README does not compare class-validator with those libraries. It is built around decorators on classes, while Joi, Zod, Yup and Ajv use their own schema definitions. Choose based on whether you already model data as classes.
New agent skills, repos and AI tools — every week
The best new skills and open-source projects, the fastest-growing repos, and one free prompt. Five minutes to read. Unsubscribe anytime.
Our verdict
Use class-validator if you are a TypeScript developer who already models request bodies or form data as classes and wants rules next to the fields. Pick a different tool if your project does not use TypeScript or decorators, or if you need a schema language that infers types from one definition.
Install options & downloads