filter-obj

Filter object keys and values into a new object using a predicate function or a list of keys.

Library
npm
v6.1.0
105stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
40/100Fair
Development Activity0
Maintenance20
Community68
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
67/100Good
Architecture75
Code Quality90
Innovation58
Learning Curve45

filter-obj is a minimal, dependency-free utility for building a new object that includes or excludes a chosen subset of another object’s own properties. It exposes two functions — includeKeys and excludeKeys — each accepting either a predicate function that receives the key, value, and source object, or a plain array/Set of keys to keep or drop.

Unlike a naive Object.keys().reduce() implementation, filter-obj preserves property descriptors (getters, setters, enumerability) via Object.getOwnPropertyDescriptor/defineProperty and correctly retains symbol-keyed properties through Reflect.ownKeys(), making it a safer drop-in for object filtering than hand-rolled alternatives.

What You Get

  • includeKeys(object, predicate) for building a new object from properties that match a predicate function
  • excludeKeys(object, predicate) for the inverse — drop properties matching a predicate
  • Support for passing an array or Set of keys directly instead of a predicate function
  • Correct handling of property descriptors, symbol keys, and non-enumerable/inherited properties
  • Full TypeScript types with distributive Pick/Omit semantics for the key-list overloads

Common Use Cases

  • Stripping internal or sensitive fields (e.g. password, tokens) before sending an object to an API response or log
  • Picking a whitelist of fields from a large config or options object
  • Building request/response DTOs by including only allowed keys from an entity object
  • Cleaning up query-string or form-data objects by excluding empty/falsy values via a predicate

Under The Hood

Architecture The entire library lives in a single index.js file with no internal layering: includeKeys is the primitive, iterating either a supplied array/Set of keys or the full Reflect.ownKeys(object) result and copying matching properties across via Object.getOwnPropertyDescriptor/defineProperty; excludeKeys is implemented purely as the complement, either negating a predicate or converting a key list to a Set and delegating back into includeKeys. This keeps the two public functions in lockstep — a fix to descriptor handling or symbol-key iteration in includeKeys automatically applies to excludeKeys with no duplicated logic.

Tech Stack The package ships as ESM-only ("type": "module") with a package.json exports map pointing to index.js and index.d.ts, targets Node.js >=18, and has zero runtime dependencies. Its only devDependencies are ava (test runner), xo (ESLint-based linter/style enforcer), and tsd (type-definition test runner) — there is no build/bundle step since the raw ESM source is published directly.

Code Quality test.js contains an extensive ava suite covering both functions across predicate, array, and Set argument forms, plus edge cases like symbol-keyed properties, non-enumerable properties, inherited prototype properties, getter/setter descriptor preservation, and __proto__ handling. index.test-d.ts exercises the type overloads with tsd. npm test runs xo (lint), ava (tests), and tsd (type tests) together, and GitHub Actions CI runs this matrix across Node 18 and 20 on every push and pull request — a comprehensive quality bar for a library of this size.

API Design The unified signature — a single function accepting either a predicate (key, value, object) => boolean or a plain array/Set of keys — merges what libraries like Lodash split into separate pick/pickBy/omit/omitBy functions into two functions total, reducing the API surface while keeping both dynamic and static filtering ergonomic. Documentation is limited to the README’s inline examples with no separate docs site or example directory, so newcomers rely on the readme and TypeScript signatures to discover behavior.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search