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

@amitdhoju/js-utils

v0.0.2

Published

String, number, array, and object utilities missing from native JavaScript

Downloads

12

Readme

@amitdhoju/js-utils

A collection of string, number, array, and object utilities missing from native JavaScript.

  • Zero dependencies
  • Dual ESM + CJS — works in Node.js, bundlers, and modern browsers
  • Fully typed — ships with .d.ts declarations
  • Tree-shakeable — import only what you use

Installation

npm install @amitdhoju/js-utils

Usage

import { capitalize, chunk, deepMerge } from "@amitdhoju/js-utils";

String

capitalize(str)

Capitalizes the first letter of a string.

capitalize("hello world") // → "Hello world"

truncate(str, maxLength, suffix?)

Truncates a string to a max length, appending a suffix (default "...") if cut.

truncate("Hello World", 7)        // → "Hell..."
truncate("Hello World", 8, "…")   // → "Hello W…"

camelToKebab(str)

Converts camelCase to kebab-case.

camelToKebab("myVariableName") // → "my-variable-name"

kebabToCamel(str)

Converts kebab-case to camelCase.

kebabToCamel("my-variable-name") // → "myVariableName"

slugify(str)

Converts a string to a URL-friendly slug.

slugify("Hello, World! 2024") // → "hello-world-2024"

countOccurrences(str, substring)

Counts non-overlapping occurrences of a substring.

countOccurrences("banana", "an") // → 2

isPalindrome(str)

Returns true if the string is a palindrome (ignores case and non-alphanumeric characters).

isPalindrome("racecar")                      // → true
isPalindrome("A man a plan a canal Panama")  // → true
isPalindrome("hello")                        // → false

padCenter(str, width, fill?)

Pads both sides of a string to center it within a given width (default fill " ").

padCenter("hi", 10)      // → "    hi    "
padCenter("hi", 10, "*") // → "****hi****"

Number

clamp(value, min, max)

Clamps a number between a minimum and maximum.

clamp(15, 0, 10)  // → 10
clamp(-5, 0, 10)  // → 0
clamp(5,  0, 10)  // → 5

randomInt(min, max)

Returns a random integer between min and max (both inclusive).

randomInt(1, 6) // → 4

roundTo(value, decimals)

Rounds a number to a specified number of decimal places.

roundTo(3.14159, 2) // → 3.14
roundTo(1000.5, 0)  // → 1001

isEven(n) / isOdd(n)

Checks whether a number is even or odd.

isEven(4) // → true
isOdd(7)  // → true

lerp(start, end, t)

Linearly interpolates between two values. t should be between 0 and 1.

lerp(0, 100, 0)    // → 0
lerp(0, 100, 0.5)  // → 50
lerp(0, 100, 1)    // → 100

toOrdinal(n)

Converts a number to its ordinal string.

toOrdinal(1)  // → "1st"
toOrdinal(2)  // → "2nd"
toOrdinal(3)  // → "3rd"
toOrdinal(11) // → "11th"
toOrdinal(21) // → "21st"

isFiniteNumber(value)

Type-safe check that a value is a finite number (not NaN, not Infinity).

isFiniteNumber(42)       // → true
isFiniteNumber(NaN)      // → false
isFiniteNumber(Infinity) // → false
isFiniteNumber("42")     // → false

Array

chunk(arr, size)

Splits an array into chunks of a given size.

chunk([1, 2, 3, 4, 5], 2) // → [[1, 2], [3, 4], [5]]

unique(arr)

Returns a new array with duplicates removed (first occurrence wins).

unique([1, 2, 2, 3, 1]) // → [1, 2, 3]

groupBy(arr, keyFn)

Groups array elements by a derived key.

const items = [
  { type: "fruit", name: "apple" },
  { type: "veg",   name: "carrot" },
  { type: "fruit", name: "banana" },
];
groupBy(items, (x) => x.type);
// → { fruit: [{...}, {...}], veg: [{...}] }

intersection(a, b)

Returns elements present in both arrays.

intersection([1, 2, 3], [2, 3, 4]) // → [2, 3]

difference(a, b)

Returns elements in a that are not in b.

difference([1, 2, 3], [2, 3]) // → [1]

shuffle(arr)

Returns a new randomly shuffled array (Fisher-Yates). Does not mutate the original.

shuffle([1, 2, 3, 4, 5]) // → [3, 1, 5, 2, 4]  (random)

range(start, end, step?)

Generates an array of numbers from start (inclusive) to end (exclusive).

range(0, 5)       // → [0, 1, 2, 3, 4]
range(0, 10, 2)   // → [0, 2, 4, 6, 8]
range(5, 0, -1)   // → [5, 4, 3, 2, 1]

sum(arr)

Returns the sum of all numbers in an array.

sum([1, 2, 3, 4, 5]) // → 15

average(arr)

Returns the arithmetic mean of all numbers in an array.

average([1, 2, 3, 4, 5]) // → 3

Object

deepMerge(target, source)

Deep merges two objects. Source values overwrite target values recursively.

deepMerge({ a: { b: 1 } }, { a: { c: 2 } })
// → { a: { b: 1, c: 2 } }

pick(obj, keys)

Returns a new object containing only the specified keys.

pick({ a: 1, b: 2, c: 3 }, ["a", "c"]) // → { a: 1, c: 3 }

omit(obj, keys)

Returns a new object with the specified keys removed.

omit({ a: 1, b: 2, c: 3 }, ["b"]) // → { a: 1, c: 3 }

deepClone(value)

Deep clones any value using the native structuredClone API.

const clone = deepClone({ a: { b: 1 } });
clone.a.b = 99; // original is unaffected

isEmpty(obj)

Returns true if an object has no own enumerable properties.

isEmpty({})       // → true
isEmpty({ a: 1 }) // → false

flattenObject(obj)

Flattens a nested object into dot-notation keys.

flattenObject({ a: { b: { c: 1 } }, d: 2 })
// → { "a.b.c": 1, "d": 2 }

invertObject(obj)

Swaps the keys and values of a flat string object.

invertObject({ a: "x", b: "y" }) // → { x: "a", y: "b" }

Development

npm install          # install dependencies
npm test             # run tests (Vitest)
npm run build        # build ESM + CJS output (tsup)
npm run lint         # lint and format check (Biome)
npm run example      # run the demo script

Adding a changeset before releasing

npx changeset        # describe your change + pick semver bump
npm run version      # apply version bump + update CHANGELOG.md
git add . && git commit -m "release: vX.Y.Z"
npm run release      # build + publish to npm

License

MIT