jsprim: JavaScript Primitive Utilities
jsprim is a utility library focused on fundamental operations for JavaScript primitive types and common object manipulations. It provides functions for deep cloning, thorough deep equality comparisons, and efficient inspection/transformation of object structures, including an O(1) `isEmpty` check and memory-efficient `flattenIter` for traversing deeply nested objects without materializing the full result array. The current stable version is 2.0.2, with the last update approximately four years ago. It targets older Node.js environments (originally requiring Node.js >=0.6.0) and uses the CommonJS module system, making it suitable for legacy projects or environments where explicit CJS interop is managed.
Common errors
-
SyntaxError: Named export 'deepCopy' not found. The requested module 'jsprim' does not provide an export named 'deepCopy'
cause Attempting to use ES module named import syntax for `jsprim`, which is a CommonJS module.fixUse CommonJS destructuring: `const { deepCopy } = require('jsprim');` -
ReferenceError: require is not defined in ES module scope
cause Attempting to use `require()` in an ES module file where `type: "module"` is set in package.json, or implicitly when Node.js treats a file as ESM.fixIf `jsprim` is the only CJS dependency, consider `import * as jsprim from 'jsprim';` if you're in an ES module context. Otherwise, ensure your file is treated as CommonJS (e.g., by using `.cjs` extension or `"type": "commonjs"` in package.json). -
Error: "depth" must be a non-negative integer
cause Providing an invalid `depth` parameter (e.g., negative number, non-integer) to `flattenObject` or `flattenIter`.fixEnsure the `depth` argument for `flattenObject` or `flattenIter` is always a non-negative integer (0 or greater).
Warnings
- gotcha The `flattenObject` and `flattenIter` functions exhibit a behavioral difference when the `depth` parameter is 0. `flattenObject` omits the array wrapping the original object in this specific case, while `flattenIter`'s behavior is logically equivalent to `flattenObject(obj, depth).forEach(func)`, which implies a consistent array-like iteration.
- gotcha This package is a CommonJS module and does not natively support ES module `import` syntax. Attempting to use `import jsprim from 'jsprim'` or `import { someFunc } from 'jsprim'` directly in an ES module environment will result in errors without proper interop configuration or a build step.
- gotcha The library has not been updated in approximately four years and targets Node.js versions as old as 0.6.0. While functional, it may not leverage modern JavaScript features, performance improvements, or security best practices introduced in newer Node.js releases.
Install
-
npm install jsprim -
yarn add jsprim -
pnpm add jsprim
Imports
- jsprim
import jsprim from 'jsprim';
const jsprim = require('jsprim'); - deepCopy
import { deepCopy } from 'jsprim';const { deepCopy } = require('jsprim'); - isEmpty
import { isEmpty } from 'jsprim';const { isEmpty } = require('jsprim');
Quickstart
const jsprim = require('jsprim');
// Example 1: Deep Copy
const originalObject = { a: 1, b: { c: 2 }, d: [3, 4] };
const copiedObject = jsprim.deepCopy(originalObject);
console.log('Deep Copy:', copiedObject);
console.log('Are copies identical? (reference check):', originalObject === copiedObject); // Should be false
console.log('Are contents deeply equal:', jsprim.deepEqual(originalObject, copiedObject)); // Should be true
// Example 2: Deep Equal
const obj1 = { x: 1, y: { z: 2 } };
const obj2 = { x: 1, y: { z: 2 } };
const obj3 = { x: 1, y: { z: 3 } };
console.log('Deep Equal (obj1, obj2):', jsprim.deepEqual(obj1, obj2)); // Should be true
console.log('Deep Equal (obj1, obj3):', jsprim.deepEqual(obj1, obj3)); // Should be false
// Example 3: Is Empty
console.log('Is {} empty?', jsprim.isEmpty({})); // Should be true
console.log('Is {a: 1} empty?', jsprim.isEmpty({ a: 1 })); // Should be false
// Example 4: Pluck
const nestedObject = {
user: {
profile: {
name: 'Alice',
age: 30
},
settings: { theme: 'dark' }
},
'user.id': '123'
};
console.log('Pluck user.profile.name:', jsprim.pluck(nestedObject, 'user.profile.name')); // Should be 'Alice'
console.log('Pluck user.id:', jsprim.pluck(nestedObject, 'user.id')); // Should be '123' (direct property takes precedence)
console.log('Pluck nonExistent.path:', jsprim.pluck(nestedObject, 'nonExistent.path')); // Should be undefined
// Example 5: flattenIter (demonstrates use without full array materialization)
const data = {
'RegionA': { 'CityX': { 'pop': 100 }, 'CityY': { 'pop': 200 } },
'RegionB': { 'CityZ': { 'pop': 300 } }
};
const flattenedResults = [];
jsprim.flattenIter(data, 2, (entry) => {
flattenedResults.push(entry);
});
console.log('Flattened results (using flattenIter):', flattenedResults);