is
`is` is a dependency-free CommonJS collection of runtime predicates for JavaScript values. It checks built-in types, null and undefined, arrays and array-like objects, plain object-like hashes, dates, errors, functions, numbers, ranges, deep equality, DOM elements, Base64, hexadecimal strings, Symbols, and BigInts. It is an old-browser compatibility utility rather than a TypeScript validator or assertion framework: predicates return booleans and do not narrow types through shipped declarations, describe failures, coerce input, or validate object schemas.
Keep it behind a compatibility boundary when legacy code already depends on its definitions. For new TypeScript or validation work, its missing types and surprising empty, NaN, Infinity, and equality semantics are strong reasons to install something else.
Use it if
- You maintain legacy CommonJS code that already relies on its exact predicate semantics
- You need boxed primitive and very old JavaScript environment handling that native typeof helpers do not cover
- You want dependency-free boolean checks and will wrap any surprising predicates behind your own named helpers
- You are testing isolated utility behavior, not validating API payloads or producing user-facing error reports
- You use TypeScript and expect type guards; version 3.3.2 ships no declaration file, so predicates do not narrow unknown values without local types
- You want modern native semantics; is.number accepts NaN, Infinity, and boxed Numbers, while is.nan returns true for every non-number
- You need an ordinary definition of empty; is.empty returns true for 0, false, NaN, null, and undefined as well as empty strings, arrays, arguments, and objects
- You need dependable mathematical validation; the source treats Infinity as both even and odd, and is.within returns true whenever any one of its three arguments is infinite
- You need schema validation or actionable errors; predicates cover individual values and mostly return booleans, with no nested shape declaration, coercion report, or issue paths
Setup reality
Install with `npm install is` and load it with `const is = require('is')`. The package has no runtime dependencies, peers, native build, credentials, or config. It publishes one CommonJS file, no exports map, no ESM build, and no TypeScript declarations; Node ESM can usually default-import CommonJS, but TypeScript projects need a local declaration or permissive compiler settings. The broad Node `>=0.4` engine and README references to ES3 reserved words explain many aliases and unusual choices, but they are not signs of a modern API design. Read predicate semantics before replacing native checks. `is.number` includes boxed numbers, NaN, and infinities. `is.nan` effectively means not a normal numeric value because it returns true for strings, objects, arrays, and booleans. `is.empty` treats all falsy primitives as empty and checks only enumerable own string keys for ordinary objects. `is.base64('')` and `is.hex('')` both return true. `is.equal` recursively compares arrays and enumerable object properties, but has no cycle detection, ignores symbol keys and prototypes for ordinary instances, and does not deeply understand Map, Set, typed arrays, or modern built-ins. `is.element` requires a global HTMLElement and therefore returns false in Node unless a DOM environment supplies it. Several comparison helpers throw TypeError for NaN or wrong argument shapes instead of returning false. In new code, prefer native predicates, a typed utility, or a schema validator with explicit semantics.
Patterns
Load the predicate collectionload-commonjs
const is = require('is')
if (is.string(value)) console.log(value.toUpperCase())The package publishes CommonJS only and has no TypeScript declaration file.
Distinguish null from undefineddistinguish-null-undefined
if (is.nil(value)) {
console.log('explicit null')
} else if (is.undef(value)) {
console.log('missing or undefined')
} else {
console.log('defined value')
}is.defined(null) is true; nil checks only null and undef checks only undefined.
Check common built-in valuescheck-built-in-types
is.array(value)
is.bool(value)
is.date(value)
is.error(value)
is.fn(value)
is.regexp(value)
is.string(value)Several predicates accept boxed primitives because they use Object.prototype.toString rather than only typeof.
Check for an ordinary object literalcheck-plain-hash
if (is.hash(value)) {
for (const key of Object.keys(value)) inspect(value[key])
}is.hash requires `value.constructor === Object`; null-prototype objects and class instances return false.
Reject invalid Date instancescheck-valid-date
if (!is.date.valid(value)) {
throw new TypeError('Expected a valid Date')
}is.date alone returns true for `new Date('bad')`; date.valid also checks that its numeric value is not NaN.
Build a finite-number checkcheck-finite-number
const isFiniteNumber = (value) =>
is.number(value) && !is.nan(value) && !is.infinite(value)
if (isFiniteNumber(input)) calculate(input)is.number by itself accepts NaN, positive and negative Infinity, and boxed Number objects.
Check an integer valuecheck-integer
if (is.integer(value)) {
console.log('finite integer')
}is.integer rejects NaN and Infinity but accepts boxed Number values, unlike Number.isInteger.
Check emptiness with explicit type gatescheck-empty-container
const emptyCollection =
(is.array(value) || is.string(value) || is.hash(value)) && is.empty(value)Do not call is.empty as a generic missing-value check unless 0, false, NaN, null, and undefined should all count as empty.
Deep-compare simple arrays and objectscompare-simple-values
const same = is.equal(
{ tags: ['a', 'b'], page: 2 },
{ tags: ['a', 'b'], page: 2 }
)Avoid cyclic or modern collection objects; the implementation has no cycle handling and no Map, Set, or typed-array semantics.
Check non-empty Base64 or hexadecimal textcheck-encoded-string
const nonEmptyBase64 = is.string(value) && value.length > 0 && is.base64(value)
const nonEmptyHex = is.string(value) && value.length > 0 && is.hex(value)Both built-in encoding predicates intentionally return true for the empty string, so add a length check when emptiness is invalid.
Check a finite inclusive range safelycheck-inclusive-range
const finite = [value, min, max].every((item) => is.number(item) && !is.infinite(item) && !is.nan(item))
const inRange = finite && is.within(value, min, max)is.within is inclusive, throws on non-numbers and NaN, and returns true if any argument is infinite.
Check Symbols and BigIntscheck-symbol-bigint
if (is.symbol(value)) console.log('symbol')
if (is.bigint(value)) console.log('bigint')The checks are guarded for environments without Symbol or BigInt and also recognize their boxed object forms.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| @sindresorhus/is | npm | Choose it for a modern TypeScript-first predicate library with detailed assertion variants |
| is-what | npm | Choose it for a smaller modern set of typed checks for common JavaScript values |
| kind-of | npm | Choose it when you need a descriptive type name rather than dozens of boolean methods |
| lodash | npm | Choose its individual isEqual, isPlainObject, and type utilities when lodash is already in the dependency graph |