Compare anything: AST, objects, arrays, strings and nested thereof

Quick Take

import { strict as assert } from "assert";
import { compare } from "ast-compare";

// Find out, does an object/array/string/nested-mix is a subset or equal to another input:
      a: {
        b: "d",
        c: [],
        e: "f",
        g: "h",
      a: {
        b: "d",
        c: [],



It compares data structures, especially AST.

We use it to compare two parsed HTML/CSS trees or their branches, but you can compare anything, it will recursively traverse arrays too. For example, it powers ast-delete-object which also works on AST's.

The default mode is similar to Tap opens in a new tab asserts t.match and the option opts.matchStrictly is similar to t.sameStrict.



In other words, it's a function which takes three input arguments, third one being optional (marked by square brackets).

It returns a boolean. This library will not mutate the input arguments.

API - Input

Input argument Type Obligatory? Description
bigObj Array or Plain object or String yes Superset, larger thing.
smallObj Array or Plain object or String yes A set of the above, smaller thing.
opts Plain object no A plain object containing settings.
  • If everything from smallObj matches everything within bigObj, this library returns true.
  • Otherwise, if there's a mismatch or something wrong with input args, it returns false.

Options object

options object's key Type Obligatory? Default Description
hungryForWhitespace Boolean no false Any chunk of whitespace (tabs, spaces, line breaks and so on) will match any other chunk of white space.
matchStrictly Boolean no false When you want to match like ===.
verboseWhenMismatches Boolean no false When set to true, instead of false the output will be a string with a message explaining what didn't match. It's for cases when it's important to report what didn't match.

API - Output

Positive answer is always boolean true.

Negative answer is either:

  • boolean false (default, opts.verboseWhenMismatches off) OR
  • string, explaining what didn't match (opts.verboseWhenMismatches on)


Sometimes you just want a yes/no answer is something a subset or equal to something. But sometimes, the whole point of comparison is to inform the user exactly what is mismatching. In the latter cases, set opts.verboseWhenMismatches to true. When there is no match, instead of Boolean false the main function will return a string with an explanatory message.

If you use this setting, you have to anticipate Boolean true OR something else (Boolean false or string) coming out from this library.


We want to check, does a deeply-nested array of objects/strings/arrays (for example, parsed AST output) is equal or is a subset of some other AST. Normally _.isMatch would do the deed but it positively matches empty arrays against any arrays what is terrible. Hence this library. Plus, this library will accept and adapt to any sources — combinations of arrays, objects and strings. That's necessary to support any parsed AST trees - HTML or CSS or whatever.

Differences from _.isMatch

"Partial comparisons will match empty array and empty object source values against any array or object value, respectively." — Lodash documentation opens in a new tab

_.isMatch opens in a new tab positively matches empty arrays to everything. This is bad when you are comparing parsed HTML/CSS trees. This library doesn't do this. An empty array will not be reported as equal to a non-empty array.

// in this library:
var res = compare(["a", "b", "c"], []);
// now, res === false


See it in the monorepo opens in a new tab, on GitHub.


To report bugs or request features or assistance, raise an issue on GitHub opens in a new tab.

Any code contributions welcome! All Pull Requests will be dealt promptly.


MIT opens in a new tab

Copyright © 2010–2021 Roy Revelt and other contributors

Related packages:

📦 ast-loose-compare 3.0.1
Compare anything: AST, objects, arrays and strings
📦 ast-delete-object 3.0.1
Delete all plain objects in AST if they contain a certain key/value pair
📦 lodash.ismatch opens in a new tab
The lodash method `_.isMatch` exported as a module
📦 ast-monkey-util 2.0.1
Utility library of AST helper functions
📦 ast-deep-contains 4.0.1
Like t.same assert on array of objects, where element order doesn't matter
📦 ast-monkey 8.0.1
Traverse and edit AST
📦 ast-contains-only-empty-space 3.0.1
Does AST contain only empty space?