Skip to content

bhaveshm05/flatmap-json

Repository files navigation

flatmap-json

A lightweight, zero-dependency TypeScript library for flattening, transforming, picking, and diffing deeply nested JSON objects.

npm version test status license

Why?

Working with deeply nested API responses in JavaScript is painful. Libraries like lodash solve it, but bring hundreds of KB you don't need. flatmap-json is a focused toolkit — does exactly one job, does it well, ships in under 5 KB.

Install

npm install flatmap-json
# or
yarn add flatmap-json
# or
pnpm add flatmap-json

Quick start

import { flatten, unflatten, pick, diff, transform } from 'flatmap-json'

// Flatten a nested object
flatten({ user: { name: 'Arjun', address: { city: 'Bengaluru' } } })
// → { "user.name": "Arjun", "user.address.city": "Bengaluru" }

// Restore it
unflatten({ "user.name": "Arjun", "user.address.city": "Bengaluru" })
// → { user: { name: "Arjun", address: { city: "Bengaluru" } } }

API

flatten(obj, options?)

Converts a deeply nested object into a single-level object with delimited keys.

flatten({ a: { b: 1 } })                     // { "a.b": 1 }
flatten({ a: { b: 1 } }, '/')                // { "a/b": 1 }  ← shorthand
flatten({ a: { b: 1 } }, { delimiter: '_' }) // { "a_b": 1 }
flatten({ a: [1, 2] }, { flattenArrays: false }) // { a: "[1,2]" }
flatten({ a: { b: { c: 1 } } }, { maxDepth: 1 }) // stops at depth 1

Options:

Option Type Default Description
delimiter string '.' Separator between key segments
maxDepth number Infinity Maximum nesting depth to flatten
flattenArrays boolean true Whether to flatten array indices

unflatten(obj, delimiter?)

Restores a flat delimited-key object back into a nested structure.

unflatten({ "a.b": 1 })         // { a: { b: 1 } }
unflatten({ "a/b": 1 }, '/')    // { a: { b: 1 } }

pick(obj, keys[], delimiter?)

Selects specific deep paths from an object. Paths use dot notation.

const obj = { a: { b: 1, c: 2 }, d: 3 }

pick(obj, ['a.b', 'd'])   // { a: { b: 1 }, d: 3 }
pick(obj, ['a.b'])        // { a: { b: 1 } }
pick(obj, ['x.y.z'])      // {}  (missing paths are silently ignored)

omit(obj, keys[], delimiter?)

Returns a new object excluding the given deep paths. Does not mutate the original.

const obj = { a: { b: 1, c: 2 }, d: 3 }

omit(obj, ['a.b'])        // { a: { c: 2 }, d: 3 }
omit(obj, ['d'])          // { a: { b: 1, c: 2 } }

transform(obj, fn, delimiter?)

Recursively maps over all leaf (primitive) values of the object. The transform function receives (value, key, fullPath).

// Double all numbers
transform({ a: 1, b: { c: 2 } }, (v) => typeof v === 'number' ? v * 2 : v)
// → { a: 2, b: { c: 4 } }

// Uppercase all strings
transform({ name: 'arjun' }, (v) => typeof v === 'string' ? v.toUpperCase() : v)
// → { name: 'ARJUN' }

// Use the path argument to selectively transform
transform(obj, (v, key, path) => {
  if (path.startsWith('user.')) return String(v)
  return v
})

renameKeys(obj, fn)

Recursively renames all keys using a mapping function.

renameKeys({ firstName: 'Arjun' }, (k) => k.replace(/([A-Z])/g, '_$1').toLowerCase())
// → { first_name: 'Arjun' }

diff(objA, objB, delimiter?)

Returns an object containing only the keys that changed, were added, or removed — with { from, to } pairs.

diff(
  { user: { name: 'Arjun', age: 28 } },
  { user: { name: 'Arjun', age: 29 } }
)
// → { "user.age": { from: 28, to: 29 } }

diff({ a: 1 }, { a: 1, b: 2 })
// → { b: { from: undefined, to: 2 } }

isEqual(objA, objB)

Deep equality check using diff under the hood.

isEqual({ a: { b: 1 } }, { a: { b: 1 } })  // true
isEqual({ a: 1 }, { a: 2 })                 // false

merge(objA, objB)

Deep merge — values in objB win on conflict. Neither input is mutated.

merge(
  { a: { b: 1, c: 2 } },
  { a: { c: 99, d: 3 } }
)
// → { a: { b: 1, c: 99, d: 3 } }

TypeScript

All functions are fully typed. Key types are exported:

import type {
  JsonObject,
  JsonValue,
  JsonPrimitive,
  FlatObject,
  DiffResult,
  FlattenOptions,
  TransformFn,
} from 'flatmap-json'

Bundle size

Export Size (minified + gzipped)
flatten + unflatten ~900 B
pick + omit ~600 B
transform + renameKeys ~500 B
diff + isEqual + merge ~700 B
Full library ~2.4 KB

Contributing

PRs and issues welcome! See CONTRIBUTING.md for guidelines.

git clone https://github.com/yourusername/flatmap-json
cd flatmap-json
npm install
npm test          # run tests
npm run build     # build to /dist

License

MIT

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors