Lodash _.isMatchWith() method

Beginner
⏱️ 7 min read
📚 Updated: May 2026
🎯 3 Code examples
🚀 3 Try-it labs
Lodash

What you’ll learn

  • How _.isMatchWith(object, source, customizer) layers rules on top of partial matching.
  • When returning true, false, or undefined from the customizer.
  • Patterns like synonym strings, numeric tolerance, or mixed strict and loose fields.
  • How this compares with _.isMatch and _.isEqualWith.

Prerequisites

You already understand _.isMatch and writing small comparator functions.

  • You know partial object equality differs from full deep equality.
  • Try-it labs load lodash from the CDN.

Overview

Reach for _.isMatchWith when acceptance tests need fuzzy equality on some fields (rounded scores, greeting synonyms, date truncation) while still enforcing strict lodash semantics elsewhere.

Still partial

Only keys in source participate—extras on object are ignored.

Per-value hooks

Customizer decides tricky pairs before default depth kicks in.

Undefined = default

Explicit undefined keeps lodash’s recursive equality behavior.

Syntax

javascript
_.isMatchWith(object, source, [customizer])
  • object: value to inspect.
  • source: required subset of properties and expected values.
  • customizer (optional): comparator invoked as (objValue, srcValue, key, object, source); omit or pass non-functions for default matching.
  • Returns: true when every source path matches subject to your overrides.
1

Synonym strings (lodash docs pattern)

Treat “hi” and “hello” as interchangeable greetings while everything else stays strict.

javascript
import isMatchWith from "lodash/isMatchWith";

function isGreeting(value) {
  return /^h(?:i|ello)$/.test(value);
}

function greetingCustomizer(objValue, srcValue) {
  if (isGreeting(objValue) && isGreeting(srcValue)) {
    return true;
  }
}

var object = { greeting: "hello" };
var source = { greeting: "hi" };

console.log(
  "custom: " + isMatchWith(object, source, greetingCustomizer) + "\n" + // true
  "plain: " + isMatchWith(object, source)                             // false
);
Try it Yourself
2

Numeric tolerance

Allow floating-point drift when comparing a measured value to an expected baseline.

javascript
import isMatchWith from "lodash/isMatchWith";

function epsilonCustomizer(objValue, srcValue, key) {
  if (key === "latencyMs") {
    return (
      typeof objValue === "number" &&
      typeof srcValue === "number" &&
      Math.abs(objValue - srcValue) < 0.5
    );
  }
}

console.log(
  "close: " +
    isMatchWith({ latencyMs: 10.2 }, { latencyMs: 10.4 }, epsilonCustomizer) + "\n" + // true
  "far: " +
    isMatchWith({ latencyMs: 12 }, { latencyMs: 10.4 }, epsilonCustomizer)             // false
);
Try it Yourself
3

Mixed strict and loose keys

Return undefined for keys you do not customize so lodash applies ordinary equality.

javascript
import isMatchWith from "lodash/isMatchWith";

function scoreCustomizer(objValue, srcValue, key) {
  if (key === "score") {
    return (
      typeof objValue === "number" &&
      typeof srcValue === "number" &&
      Math.abs(objValue - srcValue) < 1
    );
  }
}

console.log(
  "bothOk: " +
    isMatchWith(
      { score: 10, id: 1 },
      { score: 10.5, id: 1 },
      scoreCustomizer
    ) + "\n" + // true (score fuzzy + id strict)
  "idFails: " +
    isMatchWith(
      { score: 10, id: 2 },
      { score: 10.5, id: 1 },
      scoreCustomizer
    )           // false
);
Try it Yourself

📋 _.isMatchWith vs related APIs

APIBehavior
_.isMatchWith(obj, src, fn)Partial shape match with optional per-value overrides.
_.isMatch(obj, src)Same subset rules; always lodash default comparisons.
_.isEqualWith(a, b, fn)Full-structure equality with customizer—not subset-based.
Predicate wrapperUse (obj) => _.isMatchWith(obj, source, fn) with _.filter or guards—lodash does not ship a separate matchesWith helper in 4.x.

Pitfalls to avoid

Customizer

Accidental looseness

Returning true too eagerly weakens guarantees—scope checks to explicit keys or types.

Nested data

Customizer depth

Nested objects still recurse; ensure overrides behave correctly for child values.

Perf

Hot paths

Heavy customizers on huge trees add cost—profile before micro-matching everywhere.

❓ FAQ

Same partial-shape rules, but each compared pair can be routed through your customizer before lodash falls back to built-in deep equality.
Return true to treat values as matching, false to fail immediately, or undefined to let lodash compare normally.
Lodash passes objValue, srcValue, key, object, and source (plus an internal stack in some builds)—your handler can ignore extras.
Same customization idea; isEqualWith compares whole structures, while isMatchWith only checks keys present in source.

Summary

  • Purpose: partial matches with hookable comparisons per property pair.
  • Remember: undefined defers to lodash; true/false decide outright.
  • Next: explore more on Lodash _.isNaN().
Did you know?

When the customizer returns undefined, lodash continues with its normal deep comparison for that pair—so you only override the cases you care about.

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful