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

@greypan/js-kit

v1.6.0

Published

JavaScript utility functions

Readme

@greypan/js-kit

JavaScript utility functions with composable plugin system

English | 简体中文

Features

  • Plugin system: Composable plugins with definePlugin, chainable .use() and .make()
  • URL: Parse and stringify URLs with query params and hash
  • Number: Precision rounding and range clamping
  • Random: Integers, floats, RGB and hex color generation
  • Timer: Debounce with leading/trailing/both timing, controllable interval with pause/resume
  • Fetch: Async middleware composition with asyncCompose
  • Shortcut: Fire-and-forget safeCall wrapper
  • Paradigms: Go-style and Rust-style Result type utilities

Install

# npm
npm install @greypan/js-kit

# pnpm
pnpm add @greypan/js-kit

# yarn
yarn add @greypan/js-kit

# bun
bun add @greypan/js-kit

Quick Start

import { definePlugin } from '@greypan/js-kit'

// Define reusable plugins
const withLogger = definePlugin(() => ({
  log: (msg: string) => console.log(msg)
}))

const withAuth = definePlugin(() => ({
  token: 'xxx'
}))

// Compose plugins with .use() and instantiate with .make()
const app = withLogger.use(withAuth).make()

app.log('hello') // 'hello'
console.log(app.token) // 'xxx'

Plugins

definePlugin(setup)

Core of the plugin system. Encapsulates functionality into composable plugins, chainable with .use(), instantiated with .make(). Plugins can register other plugins internally, and all APIs merge into the final instance.

import { definePlugin } from '@greypan/js-kit'

const withConfig = definePlugin(() => ({
  apiUrl: 'https://api.example.com'
}))

const ctx = withConfig.make()
console.log(ctx.apiUrl) // 'https://api.example.com'

defineEventEmitter<E>(options?)

Type-safe event emitter plugin with on, off, emit methods.

import { defineEventEmitter } from '@greypan/js-kit'

const emitter = defineEventEmitter<{
  data: [payload: { id: number }]
  error: [err: Error]
}>()

const ctx = emitter.make()
ctx.on('data', payload => console.log(payload.id))
ctx.emit('data', { id: 1 })

defineBatchEmitter<S>(options?)

Batched event emitter. Collects events and flushes them as a batch after a delay.

import { defineBatchEmitter } from '@greypan/js-kit'

const batch = defineBatchEmitter<{ id: number }>({
  onFlushed: items => console.log('Flushed', items.length, 'items')
})

const ctx = batch.make()
ctx.emit({ id: 1 })
ctx.emit({ id: 2 })

defineLoopQueue<T>(options)

Async queue that processes items sequentially with auto-consume, pause/resume support.

import { defineLoopQueue } from '@greypan/js-kit'

const queue = defineLoopQueue<string>({
  onConsume: async item => {
    console.log('Processing:', item)
  }
})

const ctx = queue.make()
ctx.push('task-1')
ctx.push('task-2')

API

definePlugin<C, D>(setup)

Core plugin factory. Creates a plugin that can be composed with .use() and instantiated with .make().

| Parameter | Type | Default | Description | | --------- | --------------- | ------- | ----------------------------------------------------------- | | setup | (ctx: D) => C | - | Setup function that receives context and returns plugin API |

PluginMade<T>

Type utility that extracts the instantiated type from a plugin factory or plugin instance.

parseUrl(url?)

Parse a URL string into a structured object. Supports relative paths.

| Parameter | Type | Default | Description | | --------- | -------- | ------- | ------------------- | | url | string | '' | URL string to parse |

stringifyUrl(opts, omitNil?)

Build a URL string from structured components.

| Parameter | Type | Default | Description | | --------- | -------------------- | ------- | --------------------------------------- | | opts | Partial<URLObject> | - | URL components: base, query, hash | | omitNil | boolean | true | Remove nil values from query |

toPrecision(val, precision)

Round a number to specified decimal precision. Supports negative precision for rounding to tens, hundreds, etc.

| Parameter | Type | Default | Description | | ----------- | -------- | ------- | ---------------------------------------------- | | val | number | - | Number to round | | precision | number | - | Decimal places (negative for integer rounding) |

clamp(val, min, max)

Clamp a number to a range. Automatically swaps min/max if inverted.

| Parameter | Type | Default | Description | | --------- | -------- | ------- | -------------- | | val | number | - | Value to clamp | | min | number | - | Minimum value | | max | number | - | Maximum value |

random(min, max)

Generate a random integer in [min, max].

| Parameter | Type | Default | Description | | --------- | -------- | ------- | ------------- | | min | number | - | Minimum value | | max | number | - | Maximum value |

randomFloat(min, max)

Generate a random float in [min, max).

| Parameter | Type | Default | Description | | --------- | -------- | ------- | ------------- | | min | number | - | Minimum value | | max | number | - | Maximum value |

randomRgb()

Generate a random RGB color string, e.g. rgb(255, 0, 0).

randomHex()

Generate a random hex color string, e.g. #ff0000.

defineControllableInterval(options)

Create a controllable interval with pause/resume support. Returns a plugin with start, pause, resume, stop methods.

| Parameter | Type | Default | Description | | --------- | -------------------------------------------- | ------- | ------------------- | | options | { callback: () => void; interval: number } | - | Timer configuration |

debounce(func, options?)

Debounce a function with configurable timing mode.

| Parameter | Type | Default | Description | | --------- | ------------------------------------------------------------------------------------ | ------- | -------------------- | | func | Function | - | Function to debounce | | options | { timing?: 'trailing' \| 'leading' \| 'both'; waitMs: number; maxWaitMs?: number } | - | Debounce options |

safeCall(fn, ...args)

Fire-and-forget wrapper. Catches sync exceptions and async rejections silently.

| Parameter | Type | Default | Description | | --------- | ---------------------- | ------- | ----------------- | | fn | (...args) => unknown | - | Function to call | | ...args | Parameters<T> | - | Arguments to pass |

asyncCompose(...fns)

Compose async middleware functions into a single pipeline.

| Parameter | Type | Default | Description | | --------- | -------------- | ------- | ------------------------------- | | ...fns | Middleware[] | - | Middleware functions to compose |

go / rust

Result type namespaces for Go-style and Rust-style error handling.

| Method | Description | | ---------------- | ------------------------------ | | ok(value) | Create success result | | err(error) | Create error result | | isOk(result) | Check if result is success | | isErr(result) | Check if result is error | | to(fn) | Wrap function to return Result | | unwrap(result) | Extract value or throw error |

Import paths:

import { go } from '@greypan/js-kit/go'
import { rust } from '@greypan/js-kit/rust'

Type Utilities

| Type | Description | | ----------------------- | ------------------------------------- | | ValueOf<T> | Union of all value types in an object | | ArrayItem<T> | Element type of an array | | ArgumentType<T> | First argument type of a function | | DeepPartial<T> | Recursive partial | | DeepRequired<T> | Recursive required | | ClassPropertyTypes<T> | Class property types | | Equal<X, Y> | Type equality check |