npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@monstermann/object

v0.5.0

Published

Functional utilities for objects.

Readme

Minified Minzipped

Functional utilities for objects.

Documentation

Features

  • Opt-in mutability with remmi
  • Reference preservation (merge(obj, { foo: true }) === obj)
  • Pipe-friendly (pipe(merge({ foo: true })(obj))
  • Graceful failure handling (get(), getOr(), getOrElse(), getOrThrow())

Installation

npm install @monstermann/object
pnpm add @monstermann/object
yarn add @monstermann/object
bun add @monstermann/object

Tree-shaking

Installation

npm install -D @monstermann/unplugin-object
pnpm -D add @monstermann/unplugin-object
yarn -D add @monstermann/unplugin-object
bun -D add @monstermann/unplugin-object

Usage

// vite.config.ts
import object from "@monstermann/unplugin-object/vite";

export default defineConfig({
    plugins: [object()],
});
// rollup.config.js
import object from "@monstermann/unplugin-object/rollup";

export default {
    plugins: [object()],
};
// rolldown.config.js
import object from "@monstermann/unplugin-object/rolldown";

export default {
    plugins: [object()],
};
// webpack.config.js
const object = require("@monstermann/unplugin-object/webpack");

module.exports = {
    plugins: [object()],
};
// rspack.config.js
const object = require("@monstermann/unplugin-object/rspack");

module.exports = {
    plugins: [object()],
};
// esbuild.config.js
import { build } from "esbuild";
import object from "@monstermann/unplugin-object/esbuild";

build({
    plugins: [object()],
});

Object

assign

function Object.assign<T extends object, U extends object>(
    target: T,
    source: U,
): T extends unknown ? Merge<T, U> : never

Merges properties from source object into target object, creating a new object.

Looser version of merge - assign allows you to redefine keys and add new properties.

Example

import { Object } from "@monstermann/object";

Object.assign({ a: 1, b: 2 }, { b: 3, c: 4 }); // { a: 1, b: 3, c: 4 }
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2 }, Object.assign({ b: 3, c: 4 })); // { a: 1, b: 3, c: 4 }

clone

function Object.clone<T extends object>(target: T): T

Creates a shallow copy of an object, unless marked as mutable with markAsMutable inside a mutation context (see @monstermann/remmi).

Example

import { Object } from "@monstermann/object";

const original = { a: 1, b: 2 };
const copy = Object.clone(original); // { a: 1, b: 2 }
import { Object } from "@monstermann/object";

const original = { a: 1, b: 2 };
const copy = pipe(original, Object.clone()); // { a: 1, b: 2 }

entries

function Object.entries<T extends object>(target: T): Entries<T>

Returns an array of key-value pairs from target object.

Example

import { Object } from "@monstermann/object";

Object.entries({ a: 1, b: 2, c: 3 }); // [["a", 1], ["b", 2], ["c", 3]]
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2, c: 3 }, Object.entries()); // [["a", 1], ["b", 2], ["c", 3]]

evolve

function Object.evolve<T extends object, U extends Evolver<T>>(
    target: T,
    evolver: U,
): T

Creates a new object with multiple properties transformed by their corresponding functions in the evolver object.

Example

import { Object } from "@monstermann/object";

Object.evolve(
    { a: 1, b: 2, c: 3 },
    {
        a: (x) => x * 2,
        c: (x) => x + 1,
    },
); // { a: 2, b: 2, c: 4 }
import { Object } from "@monstermann/object";

pipe(
    { a: 1, b: 2, c: 3 },
    Object.evolve({
        a: (x) => x * 2,
        c: (x) => x + 1,
    }),
); // { a: 2, b: 2, c: 4 }

forEach

function Object.forEach<T extends object>(
    target: T,
    fn: ForEachCallback<T>,
): T

Executes fn function for each key-value pair in target object and returns the original object.

Example

import { Object } from "@monstermann/object";

Object.forEach({ a: 1, b: 2 }, ([key, value]) => console.log(key, value)); // { a: 1, b: 2 }
import { Object } from "@monstermann/object";

pipe(
    { a: 1, b: 2 },
    Object.forEach(([key, value]) => console.log(key, value)),
); // { a: 1, b: 2 }

fromEntries

function Object.fromEntries(): <
    const Entries extends IterableContainer<Entry>,
>(
    entries: Entries,
) => Simplify<FromEntries<Entries>>

Creates an object from an array of key-value pairs (entries). Each entry should be a tuple of [key, value].

Example

import { Object } from "@monstermann/object";

Object.fromEntries([
    ["a", 1],
    ["b", 2],
    ["c", 3],
]); // { a: 1, b: 2, c: 3 }
import { Object } from "@monstermann/object";

pipe(
    [
        ["a", 1],
        ["b", 2],
        ["c", 3],
    ],
    Object.fromEntries(),
); // { a: 1, b: 2, c: 3 }

get

function Object.get<
    T extends object,
    U extends keyof AllUnionFields<T>,
>(target: T, key: U): AllUnionFields<T>[U]

Returns the value of key property from target object, or undefined if not found.

Example

import { Object } from "@monstermann/object";

Object.get({ a: 1, b: 2 }, "a"); // 1
Object.get({ a: 1, b: 2 }, "c"); // undefined
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2 }, Object.get("a")); // 1
pipe({ a: 1, b: 2 }, Object.get("c")); // undefined

getOr

function Object.getOr<
    T extends object,
    U extends keyof AllUnionFields<T>,
    V,
>(
    target: T,
    key: U,
    or: V,
): Exclude<AllUnionFields<T>[U] | V, null | undefined>

Returns the value of key property from target object, or the or value if not found or nullish.

Example

import { Object } from "@monstermann/object";

Object.getOr({ a: 1, b: 2 }, "a", 0); // 1
Object.getOr({ a: 1, b: 2 }, "c", 0); // 0
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2 }, Object.getOr("a", 0)); // 1
pipe({ a: 1, b: 2 }, Object.getOr("c", 0)); // 0

getOrElse

function Object.getOrElse<
    T extends object,
    U extends keyof AllUnionFields<T>,
    V,
>(
    target: T,
    key: U,
    orElse: (target: NoInfer<T>) => V,
): Exclude<AllUnionFields<T>[U] | V, null | undefined>

Returns the value of key property from target object, or the result of calling orElse function with target if not found or nullish.

Example

import { Object } from "@monstermann/object";

Object.getOrElse({ a: 1, b: 2 }, "a", () => 0); // 1
Object.getOrElse({ a: 1, b: 2 }, "c", (obj) => Object.keys(obj).length); // 2
import { Object } from "@monstermann/object";

pipe(
    { a: 1, b: 2 },
    Object.getOrElse("a", () => 0),
); // 1

pipe(
    { a: 1, b: 2 },
    Object.getOrElse("c", (obj) => Object.keys(obj).length),
); // 2

getOrThrow

function Object.getOrThrow<
    T extends object,
    U extends keyof AllUnionFields<T>,
>(
    target: T,
    key: U,
): Exclude<AllUnionFields<T>[U], null | undefined>

Returns the value of key property from target object, or throws an error if not found or null/undefined.

Example

import { Object } from "@monstermann/object";

Object.getOrThrow({ a: 1, b: 2 }, "a"); // 1
Object.getOrThrow({ a: 1, b: 2 }, "c"); // throws FnError
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2 }, Object.getOrThrow("a")); // 1
pipe({ a: 1, b: 2 }, Object.getOrThrow("c")); // throws FnError

hasKey

function Object.hasKey<T extends object, U extends KeysOfUnion<T>>(
    target: T,
    key: U,
): target is HasKey<T, U>

Checks if target object has the specified key property.

Example

import { Object } from "@monstermann/object";

Object.hasKey({ a: 1, b: 2 }, "a"); // true
Object.hasKey({ a: 1, b: 2 }, "c"); // false
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2 }, Object.hasKey("a")); // true
pipe({ a: 1, b: 2 }, Object.hasKey("c")); // false

hasProp

function Object.hasProp<
    T extends object,
    U extends KeysOfUnion<T>,
>(target: T, key: U): target is HasProp<T, U>

Checks if target object has the specified key property with a non-null and non-undefined value.

Example

import { Object } from "@monstermann/object";

Object.hasProp({ a: 1, b: null }, "a"); // true
Object.hasProp({ a: 1, b: null }, "b"); // false
import { Object } from "@monstermann/object";

pipe({ a: 1, b: null }, Object.hasProp("a")); // true
pipe({ a: 1, b: null }, Object.hasProp("b")); // false

is

function Object.is(
    target: unknown,
): target is Record<PropertyKey, unknown>

Checks if target is a plain object.

Example

import { Object } from "@monstermann/object";

Object.is({ a: 1 }); // true
Object.is([]); // false
Object.is(null); // false
Object.is("hello"); // false
import { Object } from "@monstermann/object";

pipe({ a: 1 }, Object.is()); // true
pipe([], Object.is()); // false
pipe(null, Object.is()); // false
pipe("hello", Object.is()); // false

isEmpty

function Object.isEmpty<T extends object>(target: T): boolean

Checks if target object has no enumerable properties.

Example

import { Object } from "@monstermann/object";

Object.isEmpty({}); // true
Object.isEmpty({ a: 1 }); // false
import { Object } from "@monstermann/object";

pipe({}, Object.isEmpty()); // true
pipe({ a: 1 }, Object.isEmpty()); // false

isShallowEqual

function Object.isShallowEqual<T extends object, U extends T>(
    target: T,
    source: U,
): target is U

Performs a shallow equality comparison between target and source objects.

Example

import { Object } from "@monstermann/object";

Object.isShallowEqual({ a: 1, b: 2 }, { a: 1, b: 2 }); // true
Object.isShallowEqual({ a: 1, b: 2 }, { a: 1, b: 3 }); // false
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2 }, Object.isShallowEqual({ a: 1, b: 2 })); // true
pipe({ a: 1, b: 2 }, Object.isShallowEqual({ a: 1, b: 3 })); // false

keys

function Object.keys<T extends object>(target: T): KeysOfUnion<T>[]

Returns an array of target object's enumerable property names.

Example

import { Object } from "@monstermann/object";

Object.keys({ a: 1, b: 2, c: 3 }); // ["a", "b", "c"]
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2, c: 3 }, Object.keys()); // ["a", "b", "c"]

map

function Object.map<T extends object, U extends keyof T>(
    target: T,
    key: U,
    transform: (value: NoInfer<T>[U]) => T[U],
): T
function Object.map<T extends object, U extends keyof T>(
    target: T,
    key: U,
    transform: (value: NoInfer<T>[U]) => T[U],
): T

Creates a new object with the key property transformed by the transform function.

Example

import { Object } from "@monstermann/object";

Object.map({ a: 1, b: 2 }, "a", (x) => x * 2); // { a: 2, b: 2 }
import { Object } from "@monstermann/object";

pipe(
    { a: 1, b: 2 },
    Object.map("a", (x) => x * 2),
); // { a: 2, b: 2 }

mapAssign

function Object.mapAssign<T extends object, U extends object>(
    target: T,
    map: (target: NoInfer<T>) => U,
): T extends unknown ? Merge<T, U> : never

Merges target object with the result of calling map function on target, creating a new object.

Looser version of mapMerge - mapAssign allows you to redefine keys and add new properties.

Example

import { Object } from "@monstermann/object";

Object.mapAssign({ a: 1, b: 2 }, (obj) => ({ c: obj.a + obj.b })); // { a: 1, b: 2, c: 3 }
import { Object } from "@monstermann/object";

pipe(
    { a: 1, b: 2 },
    Object.mapAssign((obj) => ({ c: obj.a + obj.b })),
); // { a: 1, b: 2, c: 3 }

mapMerge

function Object.mapMerge<T extends object>(
    target: T,
    map: (target: NoInfer<T>) => Partial<NoInfer<T>>,
): T

Merges target object with the result of calling map function on target, creating a new object with existing keys updated.

Example

import { Object } from "@monstermann/object";

Object.mapMerge({ a: 1, b: 2 }, (obj) => ({ a: obj.a * 2 })); // { a: 2, b: 2 }
import { Object } from "@monstermann/object";

pipe(
    { a: 1, b: 2 },
    Object.mapMerge((obj) => ({ a: obj.a * 2 })),
); // { a: 2, b: 2 }

matches

function Object.matches<T extends object, U extends T>(
    target: T,
    props: Partial<U>,
): target is Matches<T, U>

Checks if all properties in props object have equal values in target object.

Example

import { Object } from "@monstermann/object";

Object.matches({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 }); // true
Object.matches({ a: 1, b: 2, c: 3 }, { a: 1, b: 3 }); // false
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2, c: 3 }, Object.matches({ a: 1, b: 2 })); // true
pipe({ a: 1, b: 2, c: 3 }, Object.matches({ a: 1, b: 3 })); // false

merge

function Object.merge<T extends object>(
    target: T,
    source: Partial<NoInfer<T>>,
): T

Merges properties from source object into target object.

Example

import { Object } from "@monstermann/object";

Object.merge({ a: 1, b: 2 }, { a: 3, c: 4 }); // { a: 3, b: 2 }
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2 }, Object.merge({ a: 3, c: 4 })); // { a: 3, b: 2 }

omit

function Object.omit<T extends object, K extends KeysOfUnion<T>>(
    target: T,
    keys: Iterable<K>,
): DistributedOmit<T, K>

Creates a new object excluding the properties specified in the keys iterable.

Example

import { Object } from "@monstermann/object";

Object.omit({ a: 1, b: 2, c: 3 }, ["a", "c"]); // { b: 2 }
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2, c: 3 }, Object.omit(["a", "c"])); // { b: 2 }

pick

function Object.pick<T extends object, K extends KeysOfUnion<T>>(
    target: T,
    keys: Iterable<K>,
): DistributedPick<T, K>

Creates a new object containing only the properties specified in the keys iterable.

Example

import { Object } from "@monstermann/object";

Object.pick({ a: 1, b: 2, c: 3 }, ["a", "c"]); // { a: 1, c: 3 }
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2, c: 3 }, Object.pick(["a", "c"])); // { a: 1, c: 3 }

propIs

function Object.propIs<
    T extends object,
    U extends keyof AllUnionFields<T>,
    const V extends AllUnionFields<T>[U],
>(target: T, key: U, value: V): target is PropIs<T, U, V>

Checks if the key property of target object is equal to the specified value using strict equality.

Example

import { Object } from "@monstermann/object";

Object.propIs({ a: 1, b: 2 }, "a", 1); // true
Object.propIs({ a: 1, b: 2 }, "a", 2); // false
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2 }, Object.propIs("a", 1)); // true
pipe({ a: 1, b: 2 }, Object.propIs("a", 2)); // false

set

function Object.set<T extends object, K extends keyof T>(
    target: T,
    key: K,
    value: T[K],
): T

Creates a new object with the key property set to value.

Example

import { Object } from "@monstermann/object";

Object.set({ a: 1, b: 2 }, "a", 3); // { a: 3, b: 2 }
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2 }, Object.set("a", 3)); // { a: 3, b: 2 }

test

function Object.test<
    T extends object,
    U extends keyof AllUnionFields<T>,
>(
    target: T,
    key: U,
    predicate: (value: AllUnionFields<T>[U]) => boolean,
): target is Test<T, U, AllUnionFields<T>[U]>

Checks if the key property of target object passes the predicate function test.

Example

import { Object } from "@monstermann/object";

Object.test({ a: 5, b: 2 }, "a", (x) => x > 3); // true
Object.test({ a: 1, b: 2 }, "a", (x) => x > 3); // false
import { Object } from "@monstermann/object";

pipe(
    { a: 5, b: 2 },
    Object.test("a", (x) => x > 3),
); // true

pipe(
    { a: 1, b: 2 },
    Object.test("a", (x) => x > 3),
); // false

testAll

function Object.testAll<
    T extends object,
    U extends TestAllPredicates<T>,
>(target: T, props: U): target is TestAllResult<T, U>

Checks if all properties in target object pass their corresponding predicate functions in props object.

Example

import { Object } from "@monstermann/object";

Object.testAll({ a: 5, b: 2 }, { a: (x) => x > 3, b: (x) => x > 0 }); // true
Object.testAll({ a: 1, b: 2 }, { a: (x) => x > 3, b: (x) => x > 0 }); // false
import { Object } from "@monstermann/object";

pipe({ a: 5, b: 2 }, Object.testAll({ a: (x) => x > 3, b: (x) => x > 0 })); // true
pipe({ a: 1, b: 2 }, Object.testAll({ a: (x) => x > 3, b: (x) => x > 0 })); // false

values

function Object.values<T extends object>(
    target: T,
): AllUnionFields<T> extends infer U ? U[keyof U][] : never

Returns an array of target object's enumerable property values.

Example

import { Object } from "@monstermann/object";

Object.values({ a: 1, b: 2, c: 3 }); // [1, 2, 3]
import { Object } from "@monstermann/object";

pipe({ a: 1, b: 2, c: 3 }, Object.values()); // [1, 2, 3]