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

tool-shack

v1.1.2

Published

Collection of usefull functions to ease work

Readme

tool-shack

npm version License: MIT TypeScript

A lightweight, zero-dependency TypeScript utility library providing essential helper functions for the browser, DOM manipulation, storage, strings, date/time formatting, scheduling, and general data validation.


Features

  • 🪶 Zero dependencies & lightweight
  • 📦 Dual module support: ESM (import) and CommonJS (require)
  • 🏷️ Full TypeScript support with built-in type definitions
  • 🌐 Browser & DOM utilities to streamline frontend development
  • ⚡ Tree-shakeable exports, including domain subpaths such as tool-shack/string

Installation

# npm
npm install tool-shack

# pnpm
pnpm add tool-shack

# yarn
yarn add tool-shack

Quick Start

import {
  slugify,
  parseDuration,
  createElement,
  isTouchSupported,
  isValidJson,
  timeAgo,
  formatBytes,
  setLocalStorage,
  getLocalStorage,
} from 'tool-shack';

// String manipulation
console.log(slugify('Hello World!')); // 'hello-world'
console.log(formatBytes(1572864)); // '1.5 MB'

// Storage
setLocalStorage('user', { name: 'Alice' });
console.log(getLocalStorage('user')); // { name: 'Alice' }

// Date & Time
console.log(parseDuration(3661000));
// { days: 0, hours: 1, minutes: 1, seconds: 1, milliseconds: 0 }
console.log(timeAgo(new Date(Date.now() - 5 * 60000))); // '5 minutes ago'

// General Validation
console.log(isValidJson('{"valid": true}')); // true

Domain subpaths export the same helpers from one module:

import { slugify } from 'tool-shack/string';
import { createElement } from 'tool-shack/dom';
import { retry } from 'tool-shack/schedule';

Available paths: browser, dateTime, dom, general, schedule, storage, string.


Modules & APIs

🌐 Browser (browser)

Utilities for feature detection, device capabilities, cookies, downloads, URL parameters, and page visibility.

| Function | Description | | -------------------------------------------------- | ----------------------------------------------------------------------------------- | | detectOS() | Detects user operating system ('ios', 'android', 'macos', etc.) | | isTouchSupported() | Checks if the current device/browser supports touch events | | isPushNotificationSupported() | Checks Web Push support (Notification, Service Worker, and PushManager) | | isScrollBehaviorSupported() | Checks if native smooth scroll behavior is supported | | isShareSupported() | Checks if the Web Share API (navigator.share) is supported | | isPageVisible() | Checks whether the page is currently visible (!document.hidden) | | pageVisibilityListener(onVisible, onHidden) | Subscribes to Page Visibility changes with a cleanup handle | | isTabFocused() | Deprecated alias of isPageVisible | | tabFocusListener(onVisible, onHidden) | Deprecated alias of pageVisibilityListener | | preferColorScheme() | Returns 'light' if that media query matches, otherwise 'dark' | | preferLightColorScheme() | Whether (prefers-color-scheme: light) matches | | preferDarkColorScheme() | Whether (prefers-color-scheme: dark) matches | | scrollToElement(element, offset?, smoothScroll?) | Scrolls the window to the element (offset default 0, smoothScroll default true) | | scrollToPosition(x, y, smoothScroll?, target?) | Scrolls window or a given element to x/y (smoothScroll default true) | | downloadFile(data, filename, mimeType?) | Programmatically triggers file download in the browser | | getQueryParams(url?) | Extracts URL search query parameters into a key-value object | | networkStatusListener(onOnline, onOffline) | Subscribes to browser online/offline events with cleanup handle | | getCookie(name) | Retrieves and decodes a cookie value by name | | setCookie(name, value, options?) | Sets a browser cookie with days, path, domain, secure, and sameSite | | deleteCookie(name, options?) | Deletes a browser cookie by name |


💾 Storage (storage)

Type-safe localStorage and sessionStorage helpers with JSON serialization, optional Base64 encoding, and exception safety.

| Function | Description | | --------------------------------------------- | ---------------------------------------------------------------------------------------------------- | | getLocalStorage(key, fallback?, options?) | JSON-parses localStorage; optional { encode: true } Base64 decode; fallback default null | | setLocalStorage(key, value, options?) | JSON-serializes to localStorage; optional Base64; returns false if the value is not serializable | | removeLocalStorage(key) | Removes item from localStorage | | clearLocalStorage() | Clears all items from localStorage | | getSessionStorage(key, fallback?, options?) | JSON-parses sessionStorage; optional { encode: true } Base64 decode; fallback default null | | setSessionStorage(key, value, options?) | JSON-serializes to sessionStorage; optional Base64; returns false if the value is not serializable | | removeSessionStorage(key) | Removes item from sessionStorage | | clearSessionStorage() | Clears all items from sessionStorage |


🧱 DOM (dom)

Simplified element creation, async/outside event handling, clipboard operations, viewport detection, and fullscreen.

| Function | Description | | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | createElement(tagName, props?) | Creates a DOM element with attributes, styles, dataset, ARIA, listeners, and children; known tags infer their element type | | addEventListener(element, listeners) | Attaches a map of event-name handlers to one element or a list of elements (no cleanup) | | addAsyncEventListener(selector, listeners, acceptBubbling?) | Attaches delegated document listeners for matching elements, with cleanup | | addClickOutsideListener(element, callback) | Triggers a callback when clicking outside a specified element, with cleanup | | appendBefore(newNode, referenceNode) | Inserts newNode immediately before referenceNode | | appendAfter(newNode, referenceNode) | Inserts newNode immediately after referenceNode | | copyToClipboard(text) | Copies text via Clipboard API with textarea fallback; returns Promise<boolean> | | fireEvent(element, eventType) | Dispatches a native Event (no detail payload) | | getElementOffset(element) | Returns document-relative { top, left } | | isInViewport(element, offset?) | Checks if an element is currently within the visible viewport | | toggleFullscreen(element?) | Toggles native fullscreen mode for an element or document root | | toggleFullscreenWithFallback(element?, options?) | Toggles fullscreen with CSS pseudo-fullscreen fallback for iOS Safari and unsupported browsers | | waitForElement(selector, timeout?, parent?) | Waits for an element to appear in the DOM using MutationObserver |


🔤 String (string)

Case conversions, string transformations, formatting, escaping, masking, and random string generators.

| Function | Description | | --------------------------------------- | ------------------------------------------------------------------------------------------------------------ | | camelCase(value) | Converts string to camelCase | | capitalize(value) | Capitalizes the first character of a string | | decodeBase64(value) | Safely decodes a Base64 string to a Unicode string | | encodeBase64(value) | Safely encodes a Unicode string to a Base64 string | | kebabCase(value) | Converts string to kebab-case | | pascalCase(value) | Converts string to PascalCase | | snakeCase(value) | Converts string to snake_case | | slugify(value, separator?) | Converts text into URL-safe slug with diacritics removal (default -) | | removeDiacritics(value) | Strips accent marks and diacritics from text | | truncate(value, maxLength, suffix?) | Truncates a string to a given length and appends a suffix (default ...) | | mask(value, options?) | Masks sensitive string characters (e.g. for card numbers or tokens) | | formatBytes(bytes, decimals?) | Formats byte number into readable string ('1.5 MB', '2 KB') | | escapeHTML(value) | Encodes &, <, >, ", and ' as HTML entities for ordinary text or quoted attributes; not a sanitizer | | unescapeHTML(value) | Unescapes HTML entities back to plain text | | byteSize(value) | Calculates the byte length of a string in UTF-8 | | randomString(length?, charset?) | Generates random string using Math.random | | randomCryptoString(length?, charset?) | Generates cryptographically secure random string using Web Crypto API |


⏱️ Date & Time (dateTime)

Date formatting, duration parsing, relative time, and calendar day comparison.

| Function | Description | | ----------------------------- | ------------------------------------------------------------------------------------ | | parseDuration(durationInMs) | Breaks down milliseconds into { days, hours, minutes, seconds, milliseconds } | | dateAsIso(date) | Formats a Date as local YYYY-MM-DDTHH:mm:ss±HH:mm (required Date; no milliseconds) | | timeAgo(date, locale?) | Formats a date into a human-readable relative string ('5 minutes ago') | | isSameDay(date1, date2) | Checks if two Date, timestamp, or date-string values fall on the same calendar day |


⚙️ General (general)

Array deduplication, picking, grouping & chunking, value comparison, number clamping, value safety checks, and JSON validation.

| Function | Description | | ------------------------ | --------------------------------------------------------------------------- | | pick(object, keys) | Creates object composed of picked object properties | | unique(array, keyFn?) | Deduplicates array items by reference or key callback | | isEqual(a, b) | Compares primitives, arrays, Dates, RegExps, and own enumerable string keys | | clamp(value, min, max) | Constrains a number between min and max boundaries | | groupBy(array, keyFn) | Groups array elements into an object by key | | chunk(array, size?) | Splits array into chunks of specified size (default 1) | | isEmpty(value) | Checks if a string, array, map, set, or object is empty | | isNil(value) | Checks if a value is null or undefined | | isValidJson(value) | Validates whether a given string is valid JSON |


⏳ Schedule (schedule)

Debouncing, throttling, async retry, sleep, and animation frames.

| Function | Description | | ------------------------------------ | -------------------------------------------------------------------------- | | debounce(fn, delay?) | Creates debounced function with .cancel() (delay default 300) | | throttle(fn, limit?) | Creates throttled function with .cancel() (limit default 300) | | sleep(ms) | Promise-based delay helper (await sleep(500)) | | retry(fn, options?) | Retries async function with exponential backoff before failing | | runAnimation(callback, autoStart?) | requestAnimationFrame loop; returns { startAnimation, stopAnimation } | | runAsync(callback) | Runs function source in a Blob Web Worker (no closures; async not awaited) |


Documentation

Full API documentation and type definitions are available at:
👉 https://storage.davidmyska.com/tool-shack/


License

MIT © David Myška