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

koyojs

v0.3.0

Published

Koyo JS — essential utilities

Readme

Koyo JS

npm node License: MIT

⚠️ APIs are stable but may still evolve before 1.0.0.

Koyo (肝要, Japanese: essential) — a zero-dependency utility library for TypeScript and JavaScript. v0.3.0

Ships as ESM, CJS, and a native Bun build. Fully typed. Works the same in Node, Bun, browsers, and edge runtimes.

Why

JavaScript has no proper standard library. The language ships with primitives and leaves everything else to the ecosystem — which sounds fine until you realize that the same operation can behave differently depending on where your code runs. A regex that works in Node may not behave the same in a browser. A built-in that exists in one runtime is missing in another. The environment shouldn't be your problem.

The npm ecosystem filled this gap, but fragility came with it. In 2016, the deletion of left-pad — a utility so small it fit in a tweet, maintained by a single unpaid developer — broke thousands of builds overnight and took much of the internet with it. The library wasn't bad code; it was a dependency that the ecosystem had quietly made load-bearing, written by someone who owed it nothing and received nothing in return.

Koyo exists because these essentials shouldn't live at the mercy of a single maintainer's patience or a registry's availability. It provides a stable, self-contained set of utilities that work the same whether your code runs in a browser, Node, Bun, or a serverless edge function — no dependencies, no surprises, no single point of failure.


Install

# npm / pnpm / yarn
npm install koyojs

# bun
bun add koyojs

Usage

import { slugify, clamp, isEmail } from "koyojs";

slugify("Hello World!");   // "hello-world"
clamp(150, 0, 100);        // 100
isEmail("[email protected]"); // true

You can also import from a specific module:

import { toCamelCase } from "koyojs/String";
import { randomInt }   from "koyojs/Number";
import { chunk }       from "koyojs/Array";
import { pick }        from "koyojs/Object";
import { gcd }         from "koyojs/Math";

API

String

| Function | Signature | Description | |---|---|---| | capitalize | (input: string) => string | Capitalize the first letter. | | toCamelCase | (input: string) => string | "hello world""helloWorld" | | toSnakeCase | (input: string) => string | "helloWorld""hello_world" | | toTitleCase | (input: string) => string | "hello world""Hello World" | | truncate | (input: string, maxLength: number) => string | Cut string to maxLength. | | ellipsify | (input: string, maxLength: number) => string | Truncate to maxLength total (including the "..."). e.g. ellipsify("Hello World", 5)"He..." | | slugify | (input: string) => string | "Hello World!""hello-world" | | isEmail | (input: string) => boolean | Validate an email address. | | isURL | (input: string) => boolean | Validate an HTTP/HTTPS URL. | | isPhoneNumber | (input: string) => boolean | Validate a phone number (E.164 + common formats). |

Array

| Function | Signature | Description | |---|---|---| | createArray | <T>(options: { strict, validate? }) => TypedArray<T> | Typed array that enforces element type. strict: true throws, strict: false warns. | | unique | <T>(arr: T[]) => T[] | Remove duplicate items. | | removeDuplicates | <T>(arr: T[]) => T[] | Alias for unique. | | flatten | <T>(arr: unknown[]) => T[] | Recursively flatten a nested array. e.g. [1,[2,[3]]][1,2,3] | | chunk | <T>(arr: T[], size: number) => T[][] | Split into sub-arrays of size. e.g. chunk([1,2,3,4], 2)[[1,2],[3,4]] | | groupBy | <T>(arr: T[], keyFn: (item: T) => string) => Record<string, T[]> | Group items by a derived key. |

Object

| Function | Signature | Description | |---|---|---| | pick | <T, K extends keyof T>(obj: T, keys: K[]) => Pick<T, K> | Return a new object with only the selected top-level keys. | | omit | <T, K extends keyof T>(obj: T, keys: K[]) => Omit<T, K> | Return a new object with the specified top-level keys removed. | | extract | <T extends object>(obj: T, paths: string[]) => Record<string, unknown> | Like pick, but resolves dot-notation nested paths. e.g. extract(obj, ['a.b.c']) | | exclude | <T extends object>(obj: T, paths: string[]) => Record<string, unknown> | Like omit, but resolves dot-notation nested paths. e.g. exclude(obj, ['a.b.c']) | | cloneDeep | <T>(value: T) => T | Deep copy that preserves prototypes, Maps, Sets, getters/setters, and handles circular references. | | cloneShallow | <T>(value: T) => T | Deep copy via structuredClone. Fast, but throws on non-serializable values and drops prototypes. |

Number

| Function | Signature | Description | |---|---|---| | clamp | (value, min, max: number) => number | Restrict a value to [min, max]. | | randomInt | (min, max: number) => number | Random integer in [min, max] (inclusive). | | sum | (values: number[]) => number | Sum an array of numbers. | | average | (values: number[]) => number | Average an array of numbers. | | isEven | (value: number) => boolean | true if the integer is even. | | isOdd | (value: number) => boolean | true if the integer is odd. |

Math

A stricter, precision-focused numeric module — C-like exactness with a Python-like API. Functions that need arbitrary-precision results (factorial, comb, perm) return bigint; every other function stays number-only. No function silently mixes the two.

| Function | Signature | Description | |---|---|---| | gcd | (a: number, b: number) => number | Greatest common divisor. | | lcm | (a: number, b: number) => number | Least common multiple. | | factorial | (n: number) => bigint | Exact factorial, arbitrary precision. | | factorialUnsafe | (n: number) => number | number-only factorial. Throws once the result would exceed Number.MAX_SAFE_INTEGER rather than returning a silently imprecise value. | | isPrime | (n: number) => boolean | Primality test via 6k±1 trial division. | | isqrt | (n: number) => number | Exact integer square root (BigInt Newton's method internally), floored for non-perfect squares. | | floorDiv | (a: number, b: number) => number | Python-style floor division. | | mod | (a: number, b: number) => number | Python-style modulo — result takes the sign of the divisor, unlike JS %. | | comb | (n: number, k: number) => bigint | n choose k, arbitrary precision. | | combUnsafe | (n: number, k: number) => number | number-only comb. Throws on overflow past Number.MAX_SAFE_INTEGER. | | perm | (n: number, k?: number) => bigint | n permute k (defaults to k = n), arbitrary precision. | | permUnsafe | (n: number, k?: number) => number | number-only perm. Throws on overflow past Number.MAX_SAFE_INTEGER. | | isClose | (a: number, b: number, options?: { relTol?, absTol? }) => boolean | Python's math.isclose — combined relative + absolute tolerance. | | isCloseAbs | (a: number, b: number, absTol: number) => boolean | Absolute-tolerance-only comparison. No relative term. | | isCloseRel | (a: number, b: number, relTol: number) => boolean | Relative-tolerance-only comparison. No absolute term. | | kahanSum | (values: number[]) => number | Compensated summation — lower accumulated error than naive reduce. | | roundTo | (value: number, decimals?: number) => number | Epsilon-corrected rounding (fixes cases like 1.005 rounding down under naive Math.round). | | copySign | (x: number, y: number) => number | Magnitude of x with the sign of y. | | degrees | (radians: number) => number | Radians to degrees. | | radians | (degrees: number) => number | Degrees to radians. | | lerp | (a: number, b: number, t: number) => number | Linear interpolation. | | hypot | (...values: number[]) => number | N-dimensional hypotenuse. | | dist | (p: number[], q: number[]) => number | Euclidean distance between two equal-dimension points. |


Development

bun install       # install dependencies
bun run build     # compile to dist/
bun run test      # run all tests
bun run check     # type-check without emitting
bun run dev       # watch mode

Benchmarks

bun run benchmark:node     # Node  — imports from dist/
bun run benchmark:bun      # Bun   — imports from src/ (native TS)
bun run benchmark:browser  # Node  — dist/ + happy-dom browser globals
bun run benchmark:all      # all three in sequence

Compares koyojs against lodash, remeda, and radash. Requires bun run build before running the Node or browser targets.


Philosophy

One file, one function. Every module lives under src/<Category>/<functionName>.ts and does exactly one thing. No file exceeds 60 lines unless strictly necessary.


Source

The repository is mirrored on two platforms — clone from whichever you prefer:

# GitHub
git clone https://github.com/DebadityaMalakar/koyojs.git

# Codeberg
git clone https://codeberg.org/debaditya/koyojs.git

License

MIT