# validata

> Type safe data validation and sanitization

Latest version **6.0.5** (published 2026-10-12) · MIT license · 0 weekly downloads

## Install

```sh
npm install validata
pnpm add validata
yarn add validata
bun add validata
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; no vulnerabilities; has provenance; recently updated; high maintenance score; high quality score.

Warnings: low downloads; no esm support.

## Facts

| | |
|---|---|
| Version | 6.0.5 |
| Published | 2026-10-12 |
| First published | 2014-05-11 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 641.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 3 |
| Maintainers | gregbacchus |
| Keywords | typescript, type-safe, typesafe, typed, validate, validator, validation, clean, cleanse, sanitise, sanitize, data validator, data clean, data cleanse, object validator, request validator |

## Links

- npm: https://www.npmjs.com/package/validata
- Repository: https://github.com/gregbacchus/validata
- Homepage: https://github.com/gregbacchus/validata#readme
- Issues: https://github.com/gregbacchus/validata/issues
- npm.io page: https://npm.io/package/validata

## Alternatives

- [vest](https://npm.io/package/vest.md) — 50.1K weekly downloads
- [@regle/core](https://npm.io/package/@regle/core.md) — 47.0K weekly downloads
- [typeof-arguments](https://npm.io/package/typeof-arguments.md) — 12.5K weekly downloads
- [@lokalise/projects-engine-contracts](https://npm.io/package/@lokalise/projects-engine-contracts.md) — 978 weekly downloads
- [@osjwnpm/nam-laboriosam-quibusdam](https://npm.io/package/@osjwnpm/nam-laboriosam-quibusdam.md) — 70 weekly downloads

## Recent versions

- 6.0.5 (latest) — 2026-10-12
- 6.0.4 — 2025-10-03
- 6.0.3 — 2025-07-03
- 6.0.2 — 2025-07-03
- 6.0.1 — 2025-07-03
- 5.0.8 — 2024-11-29
- 5.0.7 — 2024-09-04
- 5.0.6 — 2023-12-10
- 5.0.5 — 2023-05-22
- 5.0.4 — 2023-03-14
- 5.0.3 — 2023-03-14
- 5.0.2 — 2023-01-18
- 5.0.1 — 2022-09-04
- 4.0.18 — 2022-05-30
- 4.0.17 — 2022-01-22
- … 71 more at https://npm.io/package/validata/versions

## README

# Validata

Type safe data validation and sanitization.

See also

- [validata-koa](https://www.npmjs.com/package/validata-koa) for more usage in [Koa](https://www.npmjs.com/package/koa)
- [validata-express](https://www.npmjs.com/package/validata-express) for more usage in [Express](https://www.npmjs.com/package/express)

## Getting started

```bash
npm i validata
```

## Basic usage

```typescript
import { asString, isObject, isString, maybeString } from 'validata';

interface Sample {
  maybeString: string | undefined;
  myString: string;
  numericString: string;
}

const sample = isObject<Sample>({
  maybeString: maybeString(), // will allow string data type or sanitize to undefined
  myString: isString(), // will allow only string data type
  numericString: asString(), // will allow string or attempt to convert to string
});

console.log(
  JSON.stringify(
    sample.process({
      maybeString: 123,
      myString: 123,
      numericString: 123,
    })
  )
);

/*
FAIL: Outputs:
{"issues":[{"path":["maybeString"],"value":123,"reason":"incorrect-type","info":{"expectedType":"string"}},{"path":["myString"],"value":123,"reason":"incorrect-type","info":{"expectedType":"string"}}]}
*/

console.log(
  JSON.stringify(
    sample.process({
      myString: '123',
      numericString: 123,
    })
  )
);

/*
SUCCESS: Outputs:
{"value":{"myString":"123","numericString":"123"}}
*/
```

## Upgrading to v6

V6 of `validata` has been marked as a breaking change as it moves the packages `luxon`, `@types/luxon` and `validata` from dependencies to peerDependencies. This better supports different package versions.

If you are using any of the validators that use these packages, you will need to install them directly into your project:

```bash
pnpm add luxon @types/luxon validata
```

## API

Checks:

- isAny
- Array
  - isArray
  - maybeArray
  - asArray
  - maybeAsArray
- Boolean
  - isBoolean
  - maybeBoolean
  - asBoolean
  - maybeAsBoolean
- Date
  - isDate
  - maybeDate
  - asDate
  - maybeAsDate
- DateTime
  - isDateTime
  - maybeDateTime
  - asDateTime
  - maybeAsDateTime
- Enum
  - isEnum
  - maybeEnum
  - asEnum
  - maybeAsEnum
- Number
  - isNumber
  - maybeNumber
  - asNumber
  - maybeAsNumber
- Object
  - isObject
  - maybeObject
  - asObject
  - maybeAsObject
- Record
  - isRecord
  - maybeRecord
  - asRecord
  - maybeAsRecord
- String
  - isString
  - maybeString
  - asString
  - maybeAsString
- Tuple
  - isTuple
  - maybeTuple
- Url
  - isUrl
  - maybeUrl
  - asUrl
  - maybeAsUrl
- isNullable
- asNullable

Types

- TypeOf

Work is done by a typed `ValueProcessor`, as returned by`isObject<T>()` or `asNumber()`.

```typescript
interface ValueProcessor<T> {
  process(value: unknown): Result<T>;
}
```

The `process()` method returns a `Result<T>`.The `Result` is either a list of issues
(meaning validation failures) or the accepted value (it may be coerced/altered from the original).

```typescript
type Result<T> = ValueResult<T> | IssueResult;

interface ValueResult<T> {
  value: T;
}

interface IssueResult {
  issues: Issue[];
}
```

## Naming conventions

### `is...` e.g. `isNumber`

- if the value is of the type it will be accepted
- `null` or `undefined` cause an issue
- otherwise it will cause an issue

### `maybe...` e.g. `maybeNumber`

- if the value is of the type it will be accepted
- `null` or `undefined` it will sanitized to undefined
- otherwise it will cause an issue

### `as...` e.g. `asNumber`

- if the value is of the type it will be accepted
- `null` or `undefined` converted to default, if provided, or cause an issue
- if the value can be converted to the type, it will be converted and used
- if the value is cannot be converted the default will be used if provided
- otherwise it will cause an issue

### `maybeAs...` e.g. `maybeAsNumber`

- if the value is of the type it will be accepted
- `null` or `undefined` converted to default, if provided, or sanitized to undefined
- if the value can be converted to the type it will be converted and used
- if the value is cannot be converted the default will be used if provided
- otherwise it will cause an issue
  // \* otherwise it will be sanitized to undefined

## Checks

### `isArray`, `maybeArray`, `asArray`, `maybeAsArray`

Usage:

```typescript
isArray(itemProcessor, options);
maybeArray(itemProcessor, options);
asArray(itemProcessor, options);
maybeAsArray(itemProcessor, options);
```

Options:

- `converter?: (value: unknown, options?: any) => T | undefined` - custom converter function, if not defined or `undefined` is returned then built in conversions will be run
- `convertOptions` - options to pass to the _converter_
- `coerceMaxLength? number` - if there are more items than this, some will be removed
- `maxLength?: number` - if there are more items than this, it's an error `max-length`
- `minLength?: number` - if there are less items than this, it's an error `min-length`
- `validator?: (value: T, options?: any, path?: Path[]) => boolean | Issue[]` - custom validation function; if false or Issue[] is returned it's an error
- `validatorOptions?: any` - options to pass to the _validator_

Example:

```typescript
isArray<number>(isNumber({ max: 20, min: 10 }), { coerceMaxLength: 7 });
```

### `isBoolean`, `maybeBoolean`, `asBoolean`, `maybeAsBoolean`

Usage:

```typescript
isBoolean(options);
maybeBoolean(options);
asBoolean(options);
maybeAsBoolean(options);
```

Options:

- `converter?: (value: unknown, options?: any) => T | undefined` - custom converter function, if not defined or `undefined` is returned then built in conversions will be run
- `convertOptions` - options to pass to the _converter_
- `validator?: (value: T, options?: any, path?: Path[]) => boolean | Issue[]` - custom validation function; if false or Issue[] is returned it's an error
- `validatorOptions?: any` - options to pass to the _validator_

### `isDate`, `maybeDate`, `asDate`, `maybeAsDate`

> NOTE: Requires peer dependencies `luxon` and `@types/luxon`.

Usage:

```typescript
isDate(options);
maybeDate(options);
asDate(options);
maybeAsDate(options);
```

Options:

- `converter?: (value: unknown, options?: any) => T | undefined` - custom converter function, if not defined or `undefined` is returned then built in conversions will be run
- `convertOptions` - options to pass to the _converter_
- `format` - custom date format used in conversion from `string` to `Date` see [Luxon formatting](https://moment.github.io/luxon/docs/manual/formatting)
- `maxFuture?: Duration` - if the value is after this duration into the future, it's an error `max-future`
- `maxPast?: Duration` - if the value is before this duration into the past, it's an error `max-past`
- `validator?: (value: T, options?: any, path?: Path[]) => boolean | Issue[]` - custom validation function; if false or Issue[] is returned it's an error
- `validatorOptions?: any` - options to pass to the _validator_

### `isDateTime`, `maybeDateTime`, `asDateTime`, `maybeAsDateTime`

Similar to above but for luxon DateTime.

> NOTE: Requires peer dependencies `luxon` and `@types/luxon`.

Usage:

```typescript
isDateTime(options);
maybeDateTime(options);
asDateTime(options);
maybeAsDateTime(options);
```

Options:

- `converter?: (value: unknown, options?: any) => T | undefined` - custom converter function, if not defined or `undefined` is returned then built in conversions will be run
- `convertOptions` - options to pass to the _converter_
- `format` - custom date format used in conversion from `string` to `Date` see [Luxon formatting](https://moment.github.io/luxon/docs/manual/formatting)
- `maxFuture?: Duration` - if the value is after this duration into the future, it's an error `max-future`
- `maxPast?: Duration` - if the value is before this duration into the past, it's an error `max-past`
- `validator?: (value: T, options?: any, path?: Path[]) => boolean | Issue[]` - custom validation function; if false or Issue[] is returned it's an error
- `validatorOptions?: any` - options to pass to the _validator_

### `isEnum`, `maybeEnum`, `asEnum`, `maybeAsEnum`

Usage:

```typescript
isEnum(Enum);
maybeEnum(Enum);
asEnum(Enum);
maybeAsEnum(Enum);
```

`asEnum` and `maybeAsEnum` accept a `default` option. The default is used when the input is `null` or `undefined`, or when it cannot be converted to an enum value. `isEnum` and `maybeEnum` do not accept defaults; without a default, an absent input to `maybeAsEnum` is sanitized to `undefined`.

Example:

```typescript
// String based Enum
enum EnumOne {
  A = 'A',
  B = 'B',
  C = 'C',
}
isEnum(EnumOne); // Allows "A", "B", "C"

// Number based Enum
enum EnumTwo {
  A,
  B,
  C,
}
isEnum(EnumTwo); // Allows 0, 1, 2

// Converting to an Enum using it's key or value
asEnum(EnumTwo); // Allows 0, 1, 2, "A", "B", "C"
asEnum(EnumTwo).process('A');       // { value: 0 }
asEnum(EnumTwo).process(0);         // { value: 0 }
asEnum(EnumTwo).process(EnumOne.A); // { value: 0 }

// Use a default when the input is absent
asEnum(EnumTwo, { default: EnumTwo.A }).process(undefined); // { value: 0 }
maybeAsEnum(EnumTwo, { default: EnumTwo.A }).process(undefined); // { value: 0 }

// Use a default when conversion fails
maybeAsEnum(EnumTwo, { default: EnumTwo.A }).process('UNKNOWN'); // { value: 0 }
```

### `isNumber`, `maybeNumber`, `asNumber`, `maybeAsNumber`

Usage:

```typescript
isNumber(options);
maybeNumber(options);
asNumber(options);
maybeAsNumber(options);
```

Options:

- `converter?: (value: unknown, options?: any) => T | undefined` - custom converter function, if not defined or `undefined` is returned then built in conversions will be run
- `convertOptions` - options to pass to the _converter_
- `coerceMin?: number` - if the value is less than this, it will be set to this value
- `coerceMax?: number` - if the value is more than this, it will be set to this value
- `max?: number` - if the value is than this, it's an error `max`
- `min?: number` - if the value is than this, it's an error `min`
- `validator?: (value: T, options?: any, path?: Path[]) => boolean | Issue[]` - custom validation function; if false or Issue[] is returned it's an error
- `validatorOptions?: any` - options to pass to the _validator_

### `isObject`, `maybeObject`, `asObject`, `maybeAsObject`

Usage:

```typescript
isObject(contract, options);
maybeObject(contract, options);
asObject(contract, options); // will parse string JSON as object
maybeAsObject(contract, options); // will parse string JSON as object
// where `contract` is Record<string, ValueProcessor>
```

Options:

- `converter?: (value: unknown, options?: any) => T | undefined` - custom converter function, if not defined or `undefined` is returned then built in conversions will be run
- `convertOptions` - options to pass to the _converter_
- `validator?: (value: T, options?: any, path?: Path[]) => boolean | Issue[]` - custom validation function; if false or Issue[] is returned it's an error
- `validatorOptions?: any` - options to pass to the _validator_

Example:

```typescript
interface Sample {
  myString: string;
  maybeString: string | undefined;
  numericString: string;
}

const check = isObject<Sample>({
  maybeString: maybeString(), // if these don't match the interface TypeScript will error
  myString: isString(),
  numericString: asString(),
});
```

### `isRecord`, `maybeRecord`, `asRecord`, `maybeAsRecord`

Usage:

```typescript
isRecord<V>(check, options);
maybeRecord<V>(check, options);
asRecord<V>(check, options);
maybeAsRecord<V>(check, options);
// where `check` is ValueProcessor<V>, and Record<string, V> is the type to be processed
```

Options:

- `keyRegex?: RegExp` - regular expression to check each key name, or it's an error `key-regex`
- `maxKeys?: number` - if the number of keys in the object is more than this, it's an error `max-keys`
- `minKeys?: number` - if the number of keys in the object is more than this, it's an error `max-keys`
- `validator?: (value: Record<string, V>, options?: any, path?: Path[]) => boolean | Issue[]` - custom validation function; if false or Issue[] is returned it's an error
- `validatorOptions?: any` - options to pass to the _validator_

Example:

```typescript
const check = isRecord(isString());
check.process({ foo: 'bar' });
```

### `isString`, `maybeString`, `asString`, `maybeAsString`

Usage:

```typescript
isString(options);
maybeString(options);
asString(options);
maybeAsString(options);
```

Options:

- `converter?: (value: unknown, options?: any) => T | undefined` - custom converter function, if not defined or `undefined` is returned then built in conversions will be run
- `convertOptions` - options to pass to the _converter_
- `limitLength?: number` - if the length of the string is more than this, it will be truncated to this length
- `padStart?: StringPadding` - pad the start of the string up to given value
- `padEnd?: StringPadding` - pad the end of the string up to given value
- `trim?: 'start' | 'end' | 'both' | 'none'` - removes the leading and/or trailing white space and line terminator characters from the string
- `regex?: RegExp` - regular expression that must be matched, or it's an error `regex`
- `maxLength?: number` - if the length of the string is more than this, it's an error `max-length`
- `minLength?: number` - if the length of the string is less than this, it's an error `min-length`
- `format:? StringFormatCheck` - extension point for string format checking, if check fails it's an issue `format` with `info.expectedFormat` set
- `validator?: (value: T, options?: any, path?: Path[]) => boolean | Issue[]` - custom validation function; if false or Issue[] is returned it's an error
- `validatorOptions?: any` - options to pass to the _validator_

StringPadding:

- `length: number` - will pad up until this length
- `padWith: string` - the value to pad with

StringFormat:

- `StringFormat.ULID()` - https://github.com/ulid/spec
- `StringFormat.UUID()` - https://www.ietf.org/rfc/rfc4122.txt
- `StringFormat.password(requirements: PasswordRequirements)` - Password format with minimum requirements
- `StringFormat.email(options: { allowDisplayName: boolean })` - requires peer dependency `validator`

Example:

```typescript
const check = isString({
  limitLength: 6,
  padStart: { length: 6, padWith: '-' },
});
```

```typescript
const check = isString({
  format: StringFormat.ULID(),
});
```

```typescript
const check = isString({
  format: StringFormat.password({
    minLength: 10, // default=8
    numberChars: 2, // default=1
    lowerCaseChars: 2, // default=1
    upperCaseChars: 2, // default=1
    specialChars: 0, // default=1
  }),
});
```

```typescript
const check = isString({
  format: StringFormat.email({ allowDisplayName: false }),
});
```

```typescript
// change case
import { pascalCase } from 'change-case';

const check = isString({
  transform: pascalCase,
});
```

```typescript
const check = isString({
  maxLength: 10,
  minLength: 8,
  regex: /^[A-Z]+$/,
});
```

```typescript
import validator from 'validator';

const check = isString({
  validator: validator.isEmail,
  validatorOptions: { allow_display_name: true },
});
```

### `isTuple`, `maybeTuple`

Usage:

```typescript
isTuple(options);
maybeTuple(options);
```

Options:

- `validator?: (value: T, options?: any, path?: Path[]) => boolean | Issue[]` - custom validation function; if false or Issue[] is returned it's an error
- `validatorOptions?: any` - options to pass to the _validator_

Example:

```typescript
type MyTuple = [number, string];
const check = isTuple([isNumber({ max: 9, min: 3 }), isString({ regex: /^\w+$/ })]);
```

### `isUrl`, `maybeUrl`, `asUrl`, `maybeAsUrl`

Working with Node's URL object

Usage:

```typescript
isUrl(options);
maybeUrl(options);
asUrl(options);
maybeAsUrl(options);
```

Options:

- `converter?: (value: unknown, options?: any) => T | undefined` - custom converter function, if not defined or `undefined` is returned then built in conversions will be run
- `convertOptions` - options to pass to the _converter_
- `setProtocol?: string` - will coerce the protocol to the given value, if present
- `protocol?: string` - given URL must have this protocol, or it's an error `invalid-protocol`
- `validator?: (value: URL, options?: any, path?: Path[]) => boolean | Issue[]` - custom validation function; if false or Issue[] is returned it's an error
- `validatorOptions?: any` - options to pass to the _validator_

Example:

```typescript
const check = asUrl({
  protocol: 'https',
});
```

### `isNullable`

Any other check can be wrapped into `isNullable` to accept `null`.

Example:

```typescript
const check = isNullable(isString({ min: 3 }));
```

### `asNullable`

Any other check can be wrapped into `asNullable` to accept `null`.

Options:

- `default` - can be `null` or return type or a function with return type of the wrapped check

Example:

```typescript
const check = asNullable(isString({ min: 3 }));
const check = asNullable(isString({ min: 3 }), { default: null });
const check = asNullable(isString({ min: 3 }), { default: 'text' });
const check = asNullable(isString({ min: 3 }), { default: () => 'text' });
```

## Types

Types can be extracted from a `ValueProcessor` or a `Contract`-like pure object.

```typescript
const sampleContract = {
  maybeString: maybeString(),
  myString: isString(),
  numericString: asString(),
};
const sample = isObject(sampleContract);

// both are same as
export type SampleContract = TypeOf<typeof sample>;
export type Sample = TypeOf<typeof sample>;
// interface Sample {
//   myString: string;
//   maybeString: string | undefined;
//   numericString: string;
// }
```

---
_Source: https://npm.io/package/validata · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
