set-value
Safely set nested object properties using dot-notation paths, without prototype pollution.
Repository Health
Technical Analysis
set-value is a small, focused npm utility for writing deeply nested values onto an object using dot-notation, array, or symbol paths — the write-side counterpart to libraries like get-value. Rather than trusting the caller’s path blindly, it explicitly rejects unsafe keys (__proto__, constructor, prototype), closing off a class of prototype-pollution bugs that plague many of the dozens of similar “set nested value” packages on npm.
Beyond basic path assignment, it supports custom separators, a pluggable split function, escaping literal dots with backslashes, and an optional shallow or custom merge strategy for combining plain-object values instead of overwriting them. An internal memoization cache keyed on the input path and options avoids re-parsing the same path string on repeated calls, which the maintainer’s own benchmarks show outperforming comparable libraries (lodash.set, dot-prop, object-path) across shallow, medium, and deep object shapes.
What You Get
- A single
set(object, path, value, options)function with no build step or class instantiation required - Built-in protection against
__proto__/constructor/prototypekey injection, which many alternative dot-prop libraries do not guard against - Support for string, symbol, and array path formats, including escaping literal separators with a backslash
- A configurable
separatorand pluggable customsplitfunction for non-dot path syntaxes - An optional
mergemode (boolean or custom function) that shallow- or deep-merges plain-object values instead of overwriting them - Path-parsing memoization via an exposed
set.cacheMap, plus aset.clear()helper to reset it
Common Use Cases
- Writing form or config values onto a nested state object from a flat field name like
user.address.city - Building or updating deeply nested configuration objects programmatically without manually checking each intermediate key
- Implementing generic “patch” utilities that accept arbitrary dot-notation paths from user input while blocking prototype-pollution payloads
- Merging partial updates into existing nested plain-object structures via the
mergeoption instead of clobbering sibling keys
Under The Hood
Architecture
The entire package is a single index.js file built from a handful of small, single-purpose closures: splitString/split parse a path into an array of string/number keys (memoized in a module-level Map keyed by the path plus a serialized options string), validateKey/isUnsafeKey reject prototype-pollution-prone keys before any assignment happens, and assignProp performs the terminal write (delete-on-undefined, shallow/custom merge, or plain overwrite). The exported setValue function walks the parsed key array, lazily creating nested objects or arrays (detected by whether the next key is numeric) as it descends, then delegates the final write to assignProp — a compact but clearly separated pipeline (parse → validate → walk → assign) rather than a monolithic function.
Tech Stack
Plain CommonJS JavaScript with no transpilation or bundling step; package.json declares only two runtime dependencies, is-plain-object (^2.0.4) and is-primitive (^3.0.1), used for type-checking during merges and key validation. Dev tooling is limited to mocha (^9.1.1) for tests and gulp-format-md/verb for generating the README from a .verb.md template. engines.node requires >=11.0, and GitHub Actions (.github/workflows/main.yml) runs the mocha suite across Node 11–16 on Ubuntu, Windows, and macOS.
Code Quality
test/test.js contains an extensive suite (300+ lines) covering prototype-pollution guards, symbol/array/string path forms, escaping, custom separators, the merge option, and edge cases like non-object targets — using Node’s core assert module under mocha rather than a heavier assertion library. An .eslintrc.json extending eslint:recommended with additional style rules enforces consistent formatting, and the CI matrix exercises multiple Node versions and OSes on every push. There is no TypeScript or type-checking layer — the codebase is untyped plain JavaScript.
What Makes It Unique The README documents head-to-head benchmarks against a long list of comparable “set nested property” packages (lodash.set, dot-prop, object-path-set, and roughly a dozen others), showing set-value outperforming them across shallow, medium, and deep object depths — a result the maintainer attributes to the path-parsing memoization cache avoiding repeated string-splitting work. Combined with its explicit rejection of unsafe prototype-chain keys (a check many of the benchmarked alternatives lack, per the maintainer’s own comparison notes), the package positions itself as both the fastest and the safest option in a crowded space of near-identical utilities.