{"id":11160,"library":"js-utils-deep","title":"JavaScript Deep Utility Functions","description":"js-utils-deep is a lightweight JavaScript utility package providing a focused set of functions for deep, recursive manipulation of objects. It includes `recursiveOmit`, which removes null, empty string, and undefined values from all nested levels of an object; `deepExtend`, designed for deeply merging properties from a source object into a target object; and `diffObject`, which identifies key-value differences between two objects, including nested structures. Currently at version 1.1.4, the library appears to be in a maintenance phase, offering stable and tested functionalities without frequent updates. Its primary differentiator is its straightforward API for common deep object tasks, providing essential recursive utilities without the added complexity of larger, more generalized utility libraries.","status":"maintenance","version":"1.1.4","language":"javascript","source_language":"en","source_url":"https://github.com/mohithg/js-utils","tags":["javascript","utility","utilities","deep","object","recursive"],"install":[{"cmd":"npm install js-utils-deep","lang":"bash","label":"npm"},{"cmd":"yarn add js-utils-deep","lang":"bash","label":"yarn"},{"cmd":"pnpm add js-utils-deep","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Use named import for ESM environments. CommonJS users should use `require` with destructuring.","wrong":"const { recursiveOmit } = require('js-utils-deep');","symbol":"recursiveOmit","correct":"import { recursiveOmit } from 'js-utils-deep';"},{"note":"Functions are exported as named exports. Avoid importing the entire module as a namespace unless specifically needed for multiple calls.","wrong":"import * as deepUtils from 'js-utils-deep'; deepUtils.deepExtend(...);","symbol":"deepExtend","correct":"import { deepExtend } from 'js-utils-deep';"},{"note":"For CommonJS environments, destructure specific functions from the main module export. The library does not support direct subpath imports for individual functions.","wrong":"const deepExtend = require('js-utils-deep/deepExtend');","symbol":"All functions (CommonJS)","correct":"const { recursiveOmit, deepExtend, diffObject } = require('js-utils-deep');"}],"quickstart":{"code":"import { recursiveOmit, deepExtend, diffObject } from 'js-utils-deep';\n\n// Example for recursiveOmit: Removes null, '', undefined from deeply nested objects\nlet objToOmit = {\n  x: {\n    y: {\n      z: ''\n    },\n    a: {\n      b: null,\n      c: undefined\n    },\n    d: null\n  },\n  e: 0,\n  f: 'hello',\n  g: []\n};\nconsole.log('Original object for omit:', JSON.stringify(objToOmit));\nconst omitted = recursiveOmit(objToOmit); // Mutates objToOmit\nconsole.log('Object after recursiveOmit:', JSON.stringify(omitted));\n// Expected: {\"e\":0,\"f\":\"hello\",\"g\":[]}\n\n// Example for deepExtend: Deeply merges source into target object\nlet targetObj = {\n  x: {\n    y: { z: '' },\n    a: { b: null, c: undefined }\n  },\n  existing: 'value'\n};\nlet sourceObj = {\n  x: {\n    y: { z: 'new_z' },\n    a: { b: 'new_b', c: 'new_c' },\n    d: 'new_d'\n  },\n  newProp: 'added'\n};\nconsole.log('Target object before extend:', JSON.stringify(targetObj));\ndeepExtend(targetObj, sourceObj); // Mutates targetObj\nconsole.log('Target object after deepExtend:', JSON.stringify(targetObj));\n// Expected: {\"x\":{\"y\":{\"z\":\"new_z\"},\"a\":{\"b\":\"new_b\",\"c\":\"new_c\"},\"d\":\"new_d\"},\"existing\":\"value\",\"newProp\":\"added\"}\n\n// Example for diffObject: Compares two objects and returns differing key-value pairs\nlet obj1 = {\n  id: 1,\n  name: 'Alpha',\n  details: { version: '1.0', status: 'active' }\n};\nlet obj2 = {\n  id: 1,\n  name: 'Beta',\n  details: { version: '1.1', owner: 'Org' },\n  tags: ['new']\n};\nconsole.log('Object 1 for diff:', JSON.stringify(obj1));\nconsole.log('Object 2 for diff:', JSON.stringify(obj2));\nconst differences = diffObject(obj1, obj2);\nconsole.log('Differences between objects:', JSON.stringify(differences));\n// Expected: {\"name\":\"Beta\",\"details\":{\"version\":\"1.1\",\"status\":\"active\",\"owner\":\"Org\"},\"tags\":[\"new\"]}","lang":"typescript","description":"Demonstrates the core functionalities of `js-utils-deep`: `recursiveOmit` to clean deeply nested objects, `deepExtend` to merge objects recursively, and `diffObject` to find differences, highlighting their usage and mutation behavior."},"warnings":[{"fix":"Before calling `deepExtend(obj1, obj2)` or `recursiveOmit(obj)`, create a deep clone of `obj1` or `obj` (e.g., `const clonedObj = JSON.parse(JSON.stringify(obj));`) and pass the clone to the function.","message":"Both `deepExtend` and `recursiveOmit` functions mutate their first argument (the target object) in place. If you need to preserve the original object, ensure you pass a deep clone of it as the first argument.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure objects passed to deep utility functions do not contain circular references. Pre-process objects to remove or break cycles if necessary, or use a library designed to handle circular references explicitly.","message":"Functions that perform deep object traversal, such as `recursiveOmit`, `deepExtend`, and `diffObject`, may encounter infinite loops and throw a 'Maximum call stack size exceeded' error if presented with objects containing circular references.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"If empty strings need to be preserved, consider pre-processing your object to replace empty strings with a placeholder or use a custom recursive function for omission.","message":"The `recursiveOmit` function treats empty strings `''` as values to be omitted, similar to `null` and `undefined`. Be aware of this behavior if empty strings have semantic meaning in your data and should be preserved.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Inspect the object structure for circular references. Refactor your object to avoid them, or preprocess the object to break cycles (e.g., by setting circular references to `null`) before passing it to `js-utils-deep` functions.","cause":"An object with circular references was passed to a recursive function like `recursiveOmit` or `deepExtend`.","error":"RangeError: Maximum call stack size exceeded"},{"fix":"Ensure all arguments passed to `js-utils-deep` functions, especially the target or source objects, are valid JavaScript objects (non-null, non-undefined).","cause":"Attempting to call a deep utility function (e.g., `deepExtend`, `recursiveOmit`) with `null` or `undefined` as a primary object argument.","error":"TypeError: Cannot convert undefined or null to object"},{"fix":"Ensure that intermediate objects exist in the target where `deepExtend` is expected to merge. For example, if `source.a.b` exists, but `target.a` is `undefined`, `deepExtend` might fail. Pre-initialize empty objects for paths if necessary, or ensure your target object's structure is compatible with the source.","cause":"This error can occur within `deepExtend` if a nested property path in the source object points to an `undefined` or `null` path in the target object where it's attempting to create a new object or set a value.","error":"TypeError: Cannot set properties of undefined (setting 'propertyName')"}],"ecosystem":"npm"}