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

@esmalley/ts-utils

v6.2.1

Published

A modular collection of TypeScript utilities for modern web development.

Readme

ts-utils

A modular collection of TypeScript utilities for modern web development.

  • Data transformation & CSV generation
  • CSS-in-JS styling & Material Design shadows
  • Comprehensive color manipulation
  • Robust date parsing and formatting
  • Object deep cloning and merging
  • Event handling systems
  • Array shuffling and combinations

Table of Contents


Installation

npm install @esmalley/ts-utils
# or
yarn add @esmalley/ts-utils

Modules

Arithmetic

Math helpers for bounding and calculation.

clamp(number, min, max)

Restricts a given number to be within the specified minimum and maximum range.

  • Example 1: Restricting UI Scroll Ensure a scroll position never goes out of bounds.
import { Arithmetic } from '@esmalley/ts-utils';

const rawScroll = -50;
const boundedScroll = Arithmetic.clamp(rawScroll, 0, 500);
console.log(boundedScroll); // Output: 0
  • Example 2: Normalizing Health Points Prevent health from exceeding maximum or falling below zero.
const currentHealth = 120;
const actualHealth = Arithmetic.clamp(currentHealth, 0, 100);
console.log(actualHealth); // Output: 100

Arrayifier

Utilities for manipulating arrays and generating sets.

shuffle(array)

Randomizes the order of elements in an array in-place using the Fisher-Yates algorithm.

  • Example 1: Shuffling a Deck
import { Arrayifier } from '@esmalley/ts-utils';

const deck = ['Ace', 'King', 'Queen', 'Jack'];
Arrayifier.shuffle(deck);
console.log(deck); // e.g., ['Queen', 'Ace', 'Jack', 'King']

getCombinations(arr, r)

Returns all possible combinations of a specific size r from an array.

  • Example 1: Tournament Matchups Get all unique pairs from a list of players.
const players = [1, 2, 3, 4];
const matchups = Arrayifier.getCombinations(players, 2);
// Output: [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]

Color

Comprehensive suite for hex, RGB, and HSL manipulation.

lerpColor(a, b, amount)

Linearly interpolates between two hexadecimal colors.

  • Example 1: Health Bar Gradient Get the color at the 50% mark between Red and Green.
import { Color } from '@esmalley/ts-utils';
const midPoint = Color.lerpColor('#ff0000', '#00ff00', 0.5);
console.log(midPoint); // Output: #7f7f00

getTextColor(color, backgroundColor)

Determines a high-contrast text color based on the background color to ensure accessibility (WCAG compliance).

  • Example 1: Dynamic Label Styling
const bg = '#000000'; // Black background
const text = Color.getTextColor('#333333', bg); 
console.log(text); // Output: #FFFFFF (returns white for better contrast)

darken(hex, amount)

Darkens a hex color by a specified percentage (0 to 1).

  • Example 1: Button Hover State
const primary = '#3498db';
const hover = Color.darken(primary, 0.2); // 20% darker

alphaColor(hex, alpha)

Converts a hex color to an rgba() string with the provided transparency.

  • Example 1: Transparent Overlay
const overlay = Color.alphaColor('#000000', 0.5);
console.log(overlay); // Output: rgba(0, 0, 0, 0.5)

CSV

Utilities for data exportation.

download(data)

Takes a nested object and triggers a browser download of a generated .csv file.

  • Example 1: Exporting User Lists
import { CSV } from '@esmalley/ts-utils';

const userData = {
  user_1: { name: 'Alice', email: '[email protected]' },
  user_2: { name: 'Bob', email: '[email protected]' }
};

CSV.download(userData); // Triggers download of 'srating-data.csv'

Dates

Powerful date parsing, formatting, and arithmetic.

parse(input, utc?)

A robust parser that handles ISO strings, US formats, timestamps, and mixed time strings (e.g., "5:00pm").

  • Example 1: Parsing US Format
import { Dates } from '@esmalley/ts-utils';
const date = Dates.parse('01/25/2026 5:30 pm');

format(date, formatString)

Formats a date using a variety of tokens (Y, y, m, n, F, M, d, j, D, l, H, h, G, g, i, s, a, A).

  • Example 1: Friendly Date String
const now = new Date();
console.log(Dates.format(now, 'l, F jS, Y')); // Output: "Sunday, January 25th, 2026"

add(date, amount, unit)

Adds a specific amount of time to a date (years, months, days, hours, minutes).

  • Example 1: Expiration Calculation
const today = new Date();
const nextYear = Dates.add(today, 1, 'years');

isSameDay(date1, date2)

Checks if two dates refer to the same calendar day, ignoring time.

  • Example 1: Calendar Highlighting
const d1 = '2026-01-25 10:00';
const d2 = '2026-01-25 18:00';
console.log(Dates.isSameDay(d1, d2)); // true

Objector

Utilities for deep object manipulation.

deepClone(obj)

Creates a full, recursive copy of an object, including Maps, Sets, Dates, and RegEx.

  • Example 1: State Immutability
import { Objector } from '@esmalley/ts-utils';
const state = { user: { id: 1 } };
const newState = Objector.deepClone(state);
newState.user.id = 2;
console.log(state.user.id); // 1 (unchanged)

extender(target, ...sources)

Deeply merges multiple source objects into a target object.

  • Example 1: Configuration Merging
const defaults = { theme: 'light', flags: { debug: false } };
const userConfig = { flags: { debug: true } };
Objector.extender(defaults, userConfig);
// defaults is now { theme: 'light', flags: { debug: true } }

Sorter

Table and collection sorting helpers.

getComparator(order, orderBy)

Returns a comparison function for use with Array.sort().

  • Example 1: Sorting Table Data
import { Sorter } from '@esmalley/ts-utils';
const rows = [{ val: 10 }, { val: 5 }, { val: 20 }];
const comparator = Sorter.getComparator('desc', 'val');
rows.sort(comparator); // [{ val: 20 }, { val: 10 }, { val: 5 }]

Style

Utilities for dynamic CSS injection and style management.

getStyleClassName(css, debug?)

Hashes a CSS object/string, generates a unique class name, and injects the style into the document head.

  • Example 1: Scoped Dynamic Styling
import { Style } from '@esmalley/ts-utils';

const className = Style.getStyleClassName({
  backgroundColor: 'red',
  '&:hover': {
    backgroundColor: 'blue'
  },
  '@media (max-width: 600px)': {
    fontSize: 12
  }
});

// Returns a unique hash like 'css-1a2b3c' and injects the CSS.

getShadow(depth)

Returns a Material Design elevation shadow string (0-24).

  • Example 1: Component Elevation
const shadow = Style.getShadow(4);
// Returns: "0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14)..."

Textor

String manipulation and linguistic utility functions.

levenshtein(a, b)

Calculates the Levenshtein distance between two strings. This is a string metric for measuring the difference between two sequences (the minimum number of single-character edits required to change one word into the other).

  • Example 1: Search Suggestions / "Did you mean?" Determine how close a user's typo is to a correct keyword.
import { Textor } from '@esmalley/ts-utils';

const input = 'Gogle';
const target = 'Google';
const distance = Textor.levenshtein(input, target);

console.log(distance); // Output: 1
if (distance <= 2) {
  console.log(`Did you mean ${target}?`);
}
  • Example 2: Deduplicating Data Check if two strings are likely the same record with minor variations.
const user1 = "Johnathan Doe";
const user2 = "Jonathan Doe";
const diff = Textor.levenshtein(user1, user2);

// A distance of 1 suggests a very high similarity
const isLikelySame = diff < 3; 

toSentenceCase(str)

Converts a string to sentence case by capitalizing the first letter of the first word and making the rest of the string lowercase. It also handles trimming whitespace.

  • Example 1: Formatting User-Generated Content Clean up a messy title submitted via a form.
const rawTitle = "  WELCOME TO THE DASHBOARD  ";
const cleanTitle = Textor.toSentenceCase(rawTitle);

console.log(cleanTitle); // Output: "Welcome to the dashboard"
  • Example 2: Normalizing Table Headers
const keys = ["USER_NAME", "EMAIL_ADDRESS"];
const labels = keys.map(k => Textor.toSentenceCase(k.replace('_', ' ')));

console.log(labels); // Output: ["User name", "Email address"]

Theme

A comprehensive Material Design-inspired theming engine providing light and dark modes with a full 50-900 color palette.

constructor(mode)

Initializes the theme engine with either 'light' or 'dark'. Throws an error if an invalid mode is provided.

  • Example 1: Dynamic Theme Initialization
import { Theme } from '@esmalley/ts-utils';

const userPreference = localStorage.getItem('theme') || 'light';
const themeEngine = new Theme(userPreference);

getTheme()

Returns the full theme object (background, primary, secondary, warning, success, error, and text palettes) based on the mode selected in the constructor.

  • Example 1: Consuming Theme in a Style Object
const myTheme = new Theme('dark').getTheme();

const headerStyle = {
  backgroundColor: myTheme.header.main,
  color: myTheme.text.primary,
  borderBottom: `1px solid ${myTheme.primary.main}`
};

getDarkTheme() / getLightTheme()

Explicitly retrieves the configuration for a specific mode, regardless of the current instance state.

  • Example 1: Comparing Modes
const theme = new Theme('light');
const dark = theme.getDarkTheme();
const light = theme.getLightTheme();

console.log(dark.background.main); // #121212
console.log(light.background.main); // #ffffff

Palette Accessors (e.g., getGrey(), getAmber(), etc.)

The class provides access to the standard Material Design color ramps.

  • Example 1: Using Specific Color Weights
const theme = new Theme('light');
const greys = theme.getGrey();

const dividerStyle = {
  backgroundColor: greys[300] // Light grey for dividers
};

const secondaryText = {
  color: greys[600] // Medium grey for subtext
};

Toaster

A global state manager for UI notifications (Toasts). It supports subscriptions, auto-dismissal, and exit animations.

subscribe(listener)

Allows a UI component (like a React or Vue component) to listen for changes to the toast list. Returns an unsubscribe function.

  • Example 1: Integrating with a Framework (React-like)
import { toaster } from '@esmalley/ts-utils';

const unsubscribe = toaster.subscribe((newList) => {
  console.log("Toasts updated:", newList);
  this.setState({ toasts: newList });
});

// Later, clean up the listener
// unsubscribe();

add(message, type)

Adds a new notification to the stack. Defaults to 'info' type. Automatically triggers a close request after 4 seconds.

  • Example 1: Error Handling
try {
  await api.save();
  toaster.add("Changes saved successfully!", "success");
} catch (e) {
  toaster.add("Failed to save changes. Please try again.", "error");
}
  • Example 2: Basic Notification
toaster.add("You have a new message."); // Defaults to 'info'

requestClose(id)

Starts the "exit" phase for a toast. It marks the toast as exiting: true, allowing the UI to play a fade-out animation before the toast is fully removed 500ms later.

  • Example 1: Manual Dismiss Button
// Inside your UI component's "X" button click handler
const handleClose = (toastId) => {
  toaster.requestClose(toastId);
};

remove(id)

Immediately removes a toast from the list without waiting for an animation or timeout.

  • Example 1: Force Clearing a specific alert
toaster.remove(currentToastId);

getToasts()

Returns the current array of active ToastItem objects.

  • Example 1: Checking Toast Count
const activeToasts = toaster.getToasts();
if (activeToasts.length > 5) {
   console.log("The user is being flooded with notifications!");
}

Kontororu (Events)

An EventTarget wrapper for managing custom listeners.

addEventListener(type, listener)

Registers an event handler.

  • Example 1: Custom Socket Events
import { Kontororu } from '@esmalley/ts-utils';
const bus = new Kontororu();
bus.addEventListener('data', (payload) => console.log(payload));