Back to list
matthewharwood

js-micro-utilities

by matthewharwood

A fantasy-themed phonics game where kids turn spelling words into creatures, places, and spells through imagination, drawing, and storytelling.

0🍴 0📅 Dec 9, 2025

SKILL.md


name: js-micro-utilities description: Zero-dependency JavaScript utilities using native APIs and just-* micro-packages. Use when manipulating objects, arrays, strings, numbers, or functions. Scan tables for native solution first (backticks), fall back to just-* package only when needed. Prefer native over dependencies. allowed-tools: Read, Write, Edit, Glob, Grep

JavaScript Micro-Utilities

Zero-dependency utilities for common JavaScript operations. Prefer native APIs (in backticks) over packages. Install just-* packages only when native solutions don't exist.

Installation

npm i just-diff just-compare just-extend just-pick just-omit  # objects
npm i just-shuffle just-partition just-range just-order-by    # arrays
npm i just-debounce-it just-throttle just-memoize just-once   # functions

Import with ESM:

import diff from 'just-diff';
import shuffle from 'just-shuffle';

Collections {}[]

NeedSolution
Deep diff two objects/arraysjust-diff
Apply JSON-patch to objectjust-diff-apply
Deep equality checkjust-compare
Deep clonestructuredClone(obj)
Extract property from arrayarr.map(x => x.prop)
Remove nullish from arrayarr.filter(x => x != null)

Objects {}

Merging

NeedSolution
Deep mergejust-extend
Shallow merge{...a, ...b} or Object.assign(target, src)

Extracting

NeedSolution
Values as arrayObject.values(obj)
Key-value pairsObject.entries(obj)
Keep only certain keysjust-pick
Exclude certain keysjust-omit

Transforming

// Filter properties
Object.fromEntries(Object.entries(obj).filter(([k, v]) => predicate(k, v)))

// Map values
Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, fn(v)]))

// Map keys
Object.fromEntries(Object.entries(obj).map(([k, v]) => [fn(k), v]))

// Swap keys/values
Object.fromEntries(Object.entries(obj).map(([k, v]) => [v, k]))

// Reduce to value
Object.entries(obj).reduce((acc, [k, v]) => ..., init)

Deep Operations

NeedSolution
Map values recursivelyjust-deep-map-values
Safe nested getobj?.a?.b?.c
Safe nested setjust-safe-set
Check nested existsobj?.a?.b !== undefined

Type Checking

NeedSolution
Is emptyjust-is-empty
Has circular refsjust-is-circular
Is primitivetypeof x !== 'object' || x === null
Better typeofjust-typeof (distinguishes array, null, date, regexp)

Arrays []

Access

NeedSolution
Last elementarr.at(-1)
All except firstarr.slice(1)
Random elementjust-random

Creating

NeedSolution
Number sequencejust-range
All combinationsjust-cartesian-product
All orderingsjust-permutations

Transforming

NeedSolution
Dedupe primitives[...new Set(arr)]
Flatten nestedarr.flat(depth)
Remove falsyarr.filter(Boolean)
Shufflejust-shuffle
Chunk into groupsjust-split

Sorting

NeedSolution
Immutable sort by proparr.toSorted((a, b) => a.prop - b.prop)
Multi-prop sortjust-order-by

Set Operations

NeedSolution
Intersectionarr1.filter(x => arr2.includes(x))
Differencearr.filter(x => !remove.includes(x))
Union (deduped)[...new Set([...a, ...b])]

Splitting

// Split at index
[arr.slice(0, i), arr.slice(i)]

// Split by predicate → [matches, nonMatches]
import partition from 'just-partition';
const [evens, odds] = partition(arr, x => x % 2 === 0);

Grouping

// Native grouping (ES2024)
Object.groupBy(arr, item => item.category)

// Array to object by key
Object.fromEntries(arr.map(x => [x[key], x]))

// Zip arrays together
import zip from 'just-zip-it';
zip([1, 2], ['a', 'b']) // [[1, 'a'], [2, 'b']]

Inserting

// Insert at index (immutable)
arr.toSpliced(i, 0, ...items)

Statistics Σ

NeedSolution
Averagearr.reduce((a, b) => a + b, 0) / arr.length
Medianjust-median
Modejust-mode
Percentilejust-percentile
Variancejust-variance
Std deviationjust-standard-deviation
Skewnessjust-skewness

Strings ""

Padding & Truncation

NeedSolution
Pad startstr.padStart(n, char)
Pad endstr.padEnd(n, char)
Truncate with ...just-truncate
Truncate at wordjust-prune

Case Conversion

NeedSolution
camelCasejust-camel-case
kebab-casejust-kebab-case
snake_casejust-snake-case
PascalCasejust-pascal-case
Capitalize firststr[0].toUpperCase() + str.slice(1)

Replacement

NeedSolution
Replace allstr.replaceAll(find, replace)
Remove whitespacestr.replaceAll(' ', '')
Template interpolationjust-template (supports {{a.b.c}} paths)

Numbers +-

NeedSolution
Clamp to rangeMath.min(Math.max(n, min), max)
Is primejust-is-prime
True modulo (neg-safe)just-modulo
Random int in rangeMath.floor(Math.random() * (max - min + 1)) + min

Functions =>

Composition

NeedSolution
Right-to-left f(g(h(x)))just-compose
Left-to-right h(g(f(x)))just-pipe

Partial Application

NeedSolution
Curryjust-curry-it
Fix args with placeholdersjust-partial-it
Swap first two argsjust-flip
Method to functionFunction.prototype.call.bind(method)

Rate Limiting

NeedSolution
Debounce (wait for pause)just-debounce-it
Throttle (once per interval)just-throttle
Run only first calljust-once

Caching

NeedSolution
Memoize by argsjust-memoize
Cache last call onlyjust-memoize-last

Quick Reference

Most Common Native

// Clone
const copy = structuredClone(obj);

// Dedupe
const unique = [...new Set(arr)];

// Last element
const last = arr.at(-1);

// Safe access
const val = obj?.deeply?.nested?.prop;

// Group by
const grouped = Object.groupBy(items, x => x.type);

// Immutable sort
const sorted = arr.toSorted((a, b) => a.name.localeCompare(b.name));

Most Common just-*

import debounce from 'just-debounce-it';
import throttle from 'just-throttle';
import pick from 'just-pick';
import omit from 'just-omit';
import shuffle from 'just-shuffle';
import partition from 'just-partition';

// Debounce input handler
const handleInput = debounce(value => search(value), 300);

// Throttle scroll handler
const handleScroll = throttle(() => updatePosition(), 100);

// Pick specific keys
const subset = pick(user, ['id', 'name', 'email']);

// Omit sensitive keys
const safe = omit(user, ['password', 'token']);

// Shuffle array
const randomized = shuffle(cards);

// Split by condition
const [valid, invalid] = partition(inputs, x => x.isValid);

Decision Tree

  1. Can native API do it? → Use native (zero deps)
  2. Is it a one-liner? → Write inline
  3. Need tested edge cases? → Use just-* package
  4. Complex algorithm? → Use just-* package

Score

Total Score

75/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新

+5
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon