the world's second best JavaScript value checker
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

#chk NPM version

Chk has been mothballed in favor of its offspring scrub ( Scrub needed to make some compatibility-breaking api changes, and so decamped to a new name. Chk works fine and I'll happily fix bugs or accept PRs if you need them, but if you're just starting, head to scrub.


Javascript's loose typing is lovely, except when it is not. chk lets you validate any value aginst any schema that you define.

Install for nodejs

npm install chk


Call chk passing in a value and a schema. Chk returns null on success or the first error it encouters on failure.

Bare minium

var chk = require('chk')
var schema = {type: 'string'}
var val = 'foo'
var err = chk(val, schema)   // err is null
val = 1
err = chk(val, schema)       // err is Error with code 'badType'

Values can be scalars or objects

schema = {
  str1: {type: 'string'},
  num1: {type: 'number'}
err = chk({str1: 'foo', num1: 2}, schema)  // err is null
err = chk({str1: 2}, schema)  // err is Error with code 'badType'


schema = {s1: {type: 'string', required: true}}
err = chk({s1: 'foo', s2: 'bar'}, schema)   // err is null
err = chk({s2: 'bar'}, schema)              // err is Error with code 'missingParam'

Value checking with delimted string enums

schema = {type: 'string', value: 'one|or|another'}
err = chk('or', schema)  // err is null
err = chk('notOne', schema)  // err is Error wtih code 'badValue'

Optionally fail on unknown object keys with option strict

schema = {foo: {type: 'string'}}
err = chk({foo: 'hello', bar: 'goodbye'}, schema)  // err is null
err = chk({foo: 'hello', bar: 'goodbye'}, schema, {strict: true})  // err is Error with code 'badParam'

Custom Validators

schema = {n1: {
  type: 'number',
  value: function(v) {
    if (v > 0) return null
    else return new Error('n1 must be greater than zero')


schema = {
  a1: {type: 'array', value: {
    type: 'object',
    validate: function(v) {
      if (v.n1 > v.n2) return new Error('object.n1 must be greater than object.n2')
      return null

Passing data to validators is easy. Within your validator, the this object refers to the top-level passed-in value, and the options object is passed through

  var schema = {
    n1: {type: 'number', default: 0},
    n2: {type: 'number', validate: n2Validate}
  function n2Validate(v, options) {
    if (v !== this.n1) return 'n2 must equal n1'
    if ( return ' must not be'
  chk({n1:1, n2:1}, schema)  // null
  chk({n1:1, n2:2}, schema)  // Error: 'n2 must equal n1'
  chk({n1:1, n2:1}, schema, {foo:true})  // Error: ' must not be'

Multiple Accepted Types

schema = {val1: {type: 'string|number|date'}}

Set Value Defaults

schema = {
  s1: {type: 'string'}
  s2: {type: 'string', default: 'goodbye'}
val = {s1: 'hello'} 
err = chk(val, schema)  // err is null
console.log(val)        // {s1: 'hello', s2: 'goodbye'}

Optionally Coerce Types

Handy for casting numbers or booleans from query strings

schema = {n1: {type: 'number'}, b1: {type: 'boolean'}}
val = {n1: '12', b2: 'true'}
err = chk(val, schema)  // err is null
console.log(val)  // {n1: 12, b2: true}  // types have been cast from string to target type
val = {n1: '12', b2: 'true'}
err = chk({n1: '12', b2: 'true'}, schema, {doNotCoerce: true}) // coercion off, err is Error with code 'badType'

Nested Objects

schema = {
  s1: {type: 'string'},
  o1: {type: 'object', value: {
    n1: {type: 'number', required: true},
    d1: {type: 'date'},
    o2: {type: 'object', value: {
      s1: {type: 'string', default: 'I am deep in my nest'}

Nested Arrays

Nested schemas are applied to each element in the array

schema = {a1: {type: 'array', value: {type: 'number'}}}
err = chk({a1: [1,2,3]})  // err is null
err = chk({a1: [1, 2, '3']})  // err is Error with code 'badType'

Arrays of Objects

schema = {
  {type: 'array' value: {type: 'object', value: {s1: {type: 'string'}, n1: {type: 'number'}}}
var err = chk([{s1: 'foo', n1: 1}, {s1: 'bar', n1: 2}])  // err is null
var err = chk([{s1: 'foo', n1: 1}, {s1: 'bar', n1: 'baz'}])  // err is Error with code 'badType'


Options and their defaults are:

    strict: false,          // do not allow unspecified properties of objects
    ignoreDefaults: false,  // do not set default values, handy for db updates
    ignoreRequired: false,  // do not enforce required, handy for db updates
    doNotCoerce: false,     // do not coerce types
    log: false              // log the arguments to each recursive chk call,
                            //     handy for debugging deeply nested schemas

Options can be set as an optional third argument to the top level call, or as properties of any schema or sub-schema. They remain set for all children unless they are overridden. For example, a top-level schema can be strict, meaning no unrecognized properties are allowed, except for one property, which can be unstrict, allowing un-specified sub-properties, except for one of its sub-properties, which must be strict, etc. For example:

schema = {
  o1: {type: 'object', value: {
    s1: {type: 'string'},
    s2: {type: 'string'},
  o2: {type: 'object', strict: false, value: {
    s1: {type: 'string'},
    s2: {type: 'string'},
    o1: {type: 'object', strict: true: value: {
      n1: {type: 'number'}
val = {
  o1: {s1: 'foo', s2: 'bar'},
  o2: {s1: 'foo', s2: 'bar', s3: 'baz}
err = chk(val, schema, {strict: true}) // err is null because o2 strict attribute overrode option
val.o2.o1 = {n2: 100}
err = chk(val, schema, {strict: true}) // err is Error because schema.o2.o1 does not allow properties other than n1


Contributions welcome. Run node test.js. Additions and improvements to test.js particularly welcome.


Copyright (c) 2013 3meters. All rights reserverd.