The library · 323 utilities

One problem.
A small solution.

Useful JavaScript, with the behavior explained. 245 run in the local lab with your own input; the rest need the DOM, callbacks or timers, so their usage is executed in tests instead.

323 examples

Clone an array

Create a new array without copying the objects inside it.

function clone(values) { return [...values]; }array

Remove duplicate values

Keep the first occurrence of each value, in its original order.

function unique(values) { return [...new Set(values)]; }array

Flatten a nested array

Turn a nested array into one sequence of values.

function flatten(values) { return values.flat(Infinity); }array

Split an array into chunks

Build consecutive chunks without changing the original array.

function chunk({ values, size }) { return Array.from({ length: Math.ceil(values.length / size) …array

Find the intersection of arrays

Return the distinct values that occur in both arrays.

function intersection({ left, right }) { const other = new Set(right); return [...new Set(left)…array

Sort numbers in ascending order

Sort a numeric copy instead of using JavaScript’s default string ordering.

function sortNumbers(values) { return [...values].sort((a, b) => a - b); }array

Sum an array of numbers

Add numeric values with an explicit result for an empty array.

function sum(values) { return values.reduce((total, value) => total + value, 0); }array

Check whether all values are equal

Compare every item with the first using Object.is.

function allEqual(values) { return values.every(value => Object.is(value, values[0])); }validator

Group objects by a key

Collect records by a string or numeric field without prototype-key collisions.

function groupBy({ values, key }) { const groups = new Map(); for (const value of values) { con…array

Pick properties from an object

Build a new object with only the requested own properties.

function pick({ value, keys }) { return Object.fromEntries(keys.filter(key => Object.hasOwn(val…object

Omit properties from an object

Keep the own enumerable fields that are not in a supplied list.

function omit({ value, keys }) { return Object.fromEntries(Object.entries(value).filter(([key])…object

Check whether an object is empty

Check for own enumerable string keys on a JSON object.

function isEmpty(value) { return Object.keys(value).length === 0; }validator

Capitalize a string

Uppercase the first Unicode code point and preserve the remaining text.

function capitalize(value) { const [first, ...rest] = Array.from(value); return first ? first.t…string

Reverse a string

Reverse Unicode code points without splitting surrogate pairs.

function reverse(value) { return Array.from(value).reverse().join(''); }string

Check a palindrome

Compare a string with its code-point reversal.

function palindrome(value) { return value === Array.from(value).reverse().join(''); }string

Create a simple URL slug

Normalize a Latin-text label into lowercase ASCII words separated by hyphens.

function slugify(value) { return value.normalize('NFKD').replace(/[\u0300-\u036f]/g, '').toLowe…string

Convert snake case to camel case

Uppercase a lowercase ASCII letter immediately after an underscore.

function camelCase(value) { return value.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase…string

Remove duplicate lines

Keep the first occurrence of every exact line while normalizing CRLF to LF.

function uniqueLines(value) { return [...new Set(value.split(/\r?\n/))].join('\n'); }string

Clamp a number to a range

Keep a number inside an inclusive minimum and maximum.

function clamp({ value, min, max }) { return Math.min(max, Math.max(min, value)); }number

Round to a number of digits

Apply decimal scaling and JavaScript rounding for display-oriented values.

function roundTo({ value, digits }) { const factor = 10 ** digits; return Math.round(value * fa…number

Check whether an integer is even

Test parity for safe integers, including zero and negative values.

function isEven(value) { return value % 2 === 0; }validator

Convert Celsius to Fahrenheit

Apply the temperature conversion without rounding the result.

function toFahrenheit(value) { return value * 9 / 5 + 32; }misc

Compare two dates

Compare validated ISO calendar dates in UTC and return -1, 0 or 1.

function compareDates({ first, second }) { return Math.sign(new Date(first).getTime() - new Dat…date & time

Check a leap year

Apply the Gregorian divisible-by-4, century and 400-year rules.

function isLeapYear(year) { return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0); }validator

Check if a URL is absolute

Detect a scheme such as https: at the start of a URL string.

function isAbsoluteUrl(url) { return /^[a-z][a-z0-9+.-]*:/i.test(url); }string

Check if a character is a digit

Test that a string is exactly one ASCII digit from 0 to 9.

function isDigit(char) { return /^[0-9]$/.test(char); }validator

Check if a date is a weekend

Return true when a YYYY-MM-DD date falls on a Saturday or Sunday.

function isWeekend(date) { return new Date(date).getUTCDay() % 6 === 0; }validator

Cast a value as an array

Wrap a single value in an array and return arrays unchanged.

function castArray(value) { return Array.isArray(value) ? value : [value]; }array

Add AM PM suffix to an hour

Turn an hour from 0 to 23 into a 12-hour label with am or pm.

function suffixAmPm(hour) { return `${hour % 12 === 0 ? 12 : hour % 12}${hour < 12 ? 'am' : 'pm…date & time

Convert a date to YYYY-MM-DD format

Format an ISO date-time as its UTC calendar date.

function formatYmd(dateTime) { return new Date(dateTime).toISOString().slice(0, 10); }date & time

Convert seconds to hh:mm:ss format

Format a whole number of seconds as zero-padded hours, minutes and seconds.

function formatSeconds(seconds) { return [Math.floor(seconds / 3600), Math.floor(seconds % 3600…date & time

Convert degrees to radians

Multiply by π and divide by 180.

function degreesToRadians(degrees) { return degrees * Math.PI / 180; }math

Check if a rectangle contains another one

Compare corners: a contains b when b’s corners sit inside or on a’s edges.

function contains({ a, b }) { return a.x1 <= b.x1 && a.y1 <= b.y1 && a.x2 >= b.x2 && a.y2 >= b.…math

Check if a path is relative

Return true unless the path starts with a slash or backslash, optionally after a drive or scheme.

function isRelative(path) { return !/^([a-z]+:)?[\\/]/i.test(path); }string

Check if two strings are anagrams

Compare the sorted, lowercased characters of both strings.

function areAnagram({ first, second }) { const sorted = text => Array.from(text.toLowerCase()).…string

Generate a hash of a string

Compute the 32-bit hash Java’s String.hashCode uses.

function hashString(text) { return text.split('').reduce((hash, char) => (Math.imul(31, hash) +…string

Strip ANSI codes from a string

Remove terminal color and cursor escape sequences.

function stripAnsi(text) { return text.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0…string

Swap case of characters in a string

Uppercase lowercase letters and lowercase the rest.

function swapCase(text) { return Array.from(text).map(char => char === char.toLowerCase() ? cha…string

Convert a string to Pascal case

Join alphanumeric words, each starting with an uppercase letter.

function toPascalCase(text) { return (text.match(/[a-zA-Z0-9]+/g) || []).map(word => `${word.ch…string

Get the file extension from a file name

Return the text after the last dot, or an empty string.

function fileExtension(name) { const dot = name.lastIndexOf('.'); return dot > 0 ? name.slice(d…string

Get the file name from a URL

Take the last path segment, ignoring the query and fragment.

function fileNameFromUrl(url) { const path = url.split(/[?#]/)[0]; return path.slice(path.lastI…string

Normalize file path slashes

Collapse runs of slashes and backslashes into single forward slashes.

function normalizePath(path) { return path.replace(/[\\/]+/g, '/'); }string

Remove spaces from a string

Delete every whitespace character, including tabs and line breaks.

function removeSpaces(text) { return text.replace(/\s/g, ''); }string

Repeat a string

Concatenate a string with itself a given number of times.

function repeat({ text, times }) { return text.repeat(times); }string

Mask the first characters of a string

Replace the first count characters with a mask character, keeping the length.

function maskStart({ text, count, mask }) { return text.slice(count).padStart(text.length, mask…string

Convert a string to camel case

Remove separators and uppercase the character after each one.

function toCamelCase(text) { return text.trim().replace(/[-_\s]+(.)?/g, (_, char) => char ? cha…string

Decapitalize a string

Lowercase the first code point and keep the rest.

function decapitalize(text) { const [first = '', ...rest] = Array.from(text); return first.toLo…string

Escape HTML special characters

Replace & < > " and ' with HTML entities.

function escapeHtml(text) { return text.replace(/[&<>"']/g, char => ({ '&': '&amp;', '<': '&lt;…string

Format a string

Replace {0}, {1}… placeholders with values in order.

function format({ template, values }) { return values.reduce((text, value, i) => text.replaceAl…string

Trim a character from both ends

Remove a repeated character from the start and the end only.

function trimCharacter({ text, char }) { const escaped = char.replace(/[.*+?^${}()|[\]\\]/g, '\…string

Truncate a string at full words

Cut at the last space that fits, then add a suffix.

function truncateWords({ text, max, suffix }) { if (text.length <= max) return text; const cut …string

Unescape HTML special characters

Turn &amp; &lt; &gt; &quot; and &#39; back into characters in one pass.

function unescapeHtml(text) { return text.replace(/&(?:amp|lt|gt|quot|#0*39);/g, entity => ({ '…string

Remove empty lines of a text document

Drop lines that are empty or whitespace only.

function removeEmptyLines(text) { return text.split(/\r?\n/).filter(line => line.trim() !== '')…string

Decode numeric HTML entities

Turn &#233; and &#xE9; style references into characters.

function decodeNumericEntities(text) { return text.replace(/&#(x[0-9a-f]+|\d+);/gi, (entity, co…string

Convert an email domain to punycode

Keep the local part and convert an international domain to its ASCII xn-- form.

function toAsciiAddress(address) { const at = address.lastIndexOf('@'); return `${address.slice…email

Check if a date is between two dates

Test whether a YYYY-MM-DD date falls inside an inclusive range.

function isBetween({ date, min, max }) { const time = Date.parse(date); return time >= Date.par…validator

Check if a date is today

Compare the UTC calendar day of a date-time with the current one.

function isToday({ dateTime, now }) { return new Date(dateTime).toISOString().slice(0, 10) === …validator

Check if a date occurs in the current year

Compare the UTC year of a date-time with the current one.

function isCurrentYear({ dateTime, now }) { return new Date(dateTime).getUTCFullYear() === new …validator

Check if a given integer is a prime number

Trial division up to the square root, without allocating an array.

function isPrime(n) { if (n < 2) return false; for (let i = 2; i * i <= n; i++) if (n % i === 0…validator

Check if a date is a weekday

Return true for a YYYY-MM-DD date from Monday to Friday.

function isWeekday(date) { return new Date(date).getUTCDay() % 6 !== 0; }validator

Check if a number is a power of 2

Use the bit trick n & (n − 1) on a positive integer.

function isPowerOfTwo(n) { return n > 0 && (n & (n - 1)) === 0; }validator

Check if a number is in a given range

Test an inclusive range whose ends may be given in any order, with an optional tolerance.

function inRange({ value, a, b, threshold = 0 }) { return Math.min(a, b) - threshold <= value &…validator

Check if a number is odd

Test that an integer leaves a remainder when divided by 2.

function isOdd(n) { return n % 2 !== 0; }validator

Check if a value is a plain object

Return true for objects whose prototype is Object.prototype or null.

function isPlainObject(value) { return value !== null && typeof value === 'object' && [null, Ob…validator

Check if a value is a string

Use Object.prototype.toString so String objects count too.

function isString(value) { return Object.prototype.toString.call(value) === '[object String]'; …validator

Check if a value is base32 encoded

Test the RFC 4648 base32 alphabet and a length that is a multiple of 8.

function isBase32(value) { return value.length % 8 === 0 && /^[A-Z2-7]+=*$/.test(value); }validator

Check if a value is base58 encoded

Test the Bitcoin base58 alphabet, which leaves out 0, O, I and l.

function isBase58(value) { return /^[A-HJ-NP-Za-km-z1-9]*$/.test(value); }validator

Check if a value is nil

Return true for null and undefined.

function isNil(value) { return value == null; }validator

Check if an array is not empty

Return true for an array with at least one item.

function isNotEmpty(value) { return Array.isArray(value) && value.length > 0; }validator

Validate a Gregorian date

Check that a year, a 1-based month and a day form a real calendar date.

function isValidDate({ year, month, day }) { const leap = year % 4 === 0 && (year % 100 !== 0 |…validator

Check if a value is a number

Accept finite numbers and numeric strings.

function isNumber(value) { return !isNaN(parseFloat(value)) && isFinite(value); }validator

Check if a value is an object

Return true for any non-null object, including arrays.

function isObject(value) { return value !== null && typeof value === 'object'; }validator

Check if a value is base64 encoded

Test standard, padded base64.

function isBase64(value) { return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}…validator

Get all subsets of an array

Build the power set, smallest subsets first.

function getSubsets(values) { return values.reduce((subsets, value) => subsets.concat(subsets.m…array

Get union of arrays

Merge arrays and keep each value once, in first-seen order.

function union(arrays) { return [...new Set(arrays.flat())]; }array

Swap two array items

Return a copy with the items at i and j exchanged.

function swapItems({ values, i, j }) { const copy = [...values]; [copy[i], copy[j]] = [copy[j],…array

Unzip an array of arrays

Regroup the n-th item of every array into the n-th output array.

function unzip(arrays) { return Array.from({ length: Math.max(0, ...arrays.map(array => array.l…array

Compare two arrays

Check the same length and the same items in the same order.

function isEqual({ a, b }) { return a.length === b.length && a.every((value, i) => Object.is(va…array

Create cartesian product

Combine one item from each set in every possible way.

function cartesian(sets) { return sets.reduce((product, set) => product.flatMap(prefix => set.m…array

Get the rank of an array of numbers

Rank each number by how many values are larger, starting at 1.

function ranking(values) { return values.map(value => values.filter(other => other > value).len…array

Zip multiple arrays

Pair the n-th items of several arrays.

function zip(arrays) { return Array.from({ length: Math.max(0, ...arrays.map(array => array.len…array

Compare two arrays regardless of order

Compare the sorted sets of distinct values.

function isEqualIgnoringOrder({ a, b }) { const normalize = values => JSON.stringify([...new Se…array

Create an array of cumulative sum

Replace each number with the running total up to it.

function accumulate(values) { let total = 0; return values.map(value => (total += value)); }array

Get all arrays of consecutive elements

Slide a window of a given size across an array.

function windows({ values, size }) { return size > values.length ? [] : values.slice(size - 1).…array

Get indices of a value in an array

Collect every index where a value appears.

function indices({ values, value }) { return values.flatMap((item, i) => (item === value ? [i] …array

Get the average of an array

Divide the sum by the count.

function average(values) { return values.reduce((sum, value) => sum + value, 0) / values.length…array

Intersperse element between elements

Insert a separator between every pair of items.

function intersperse({ values, separator }) { return values.flatMap((value, i) => (i === 0 ? [v…array

Sort an array of items by given key

Return a copy sorted by one field, ascending.

function sortBy({ values, key }) { return [...values].sort((a, b) => (a[key] > b[key] ? 1 : a[k…array

Check if an array is empty

Return true for an array without items.

function isEmptyArray(value) { return Array.isArray(value) && !value.length; }array

Get all nth items of an array

Keep every nth item, starting with the nth.

function getNthItems({ values, nth }) { return values.filter((_, i) => i % nth === nth - 1); }array

Merge two arrays

Concatenate two arrays, optionally dropping duplicates.

function merge({ a, b, unique = false }) { return unique ? [...new Set([...a, ...b])] : [...a, …array

Repeat an array

Concatenate an array with itself n times.

function repeatArray({ values, times }) { return Array(times).fill(values).flat(); }array

Add an ordinal suffix to a number

Append st, nd, rd or th to a positive integer.

function addOrdinal(n) { return `${n}${['st', 'nd', 'rd'][((((n + 90) % 100) - 10) % 10) - 1] |…number

Calculate Fibonacci numbers

Return the nth Fibonacci number with memoized recursion.

function fibonacci(n, memo = {}) { return memo[n] || (n <= 2 ? 1 : (memo[n] = fibonacci(n - 1, …number

Calculate the division of numbers

Divide the first number by each of the others in turn.

function division(values) { return values.reduce((a, b) => a / b); }number

Subtract numbers

Subtract each number from the first in turn.

function subtract(values) { return values.reduce((a, b) => a - b); }number

Convert a number to equivalent characters

Turn a zero-based index into a spreadsheet-style column name.

function toChars(n) { return `${n >= 26 ? toChars(Math.floor(n / 26) - 1) : ''}${'ABCDEFGHIJKLM…number

Multiply numbers

Multiply numbers from left to right.

function multiply(values) { return values.reduce((a, b) => a * b); }number

Convert decimal to binary recursively

Build the binary digits of a non-negative integer as a decimal-looking number.

function decToBinary(num) { return num === 0 ? 0 : (num % 2) + 10 * decToBinary(Math.floor(num …number

Prefix an integer with zeros

Pad a non-negative integer to a given width.

function prefixWithZeros({ n, length }) { return String(n).padStart(length, '0'); }number

Wrap a number between two values

Map a number into [min, max) like an angle or a carousel index.

function wrap({ num, min, max }) { return ((((num - min) % (max - min)) + (max - min)) % (max -…number

Check if a point is inside a rectangle

Compare the point with the rectangle’s edges.

function isInside({ point, rect }) { return point.x > rect.left && point.x < rect.right && poin…math

Convert radians to degrees

Multiply by 180 and divide by π.

function radiansToDegrees(radians) { return radians * 180 / Math.PI; }math

Linear scale a number between ranges

Map a value from one range onto another.

function linearScale({ value, inMin, inMax, outMin, outMax }) { return ((value - inMin) * (outM…math

Check if multiple objects are equal

Compare JSON serializations with the first object.

function areEqual(objects) { return objects.every(object => JSON.stringify(object) === JSON.str…object

Get the value at given path of an object

Follow a dot-separated path, stopping at a missing step.

function getValue({ path, object }) { return path.split('.').reduce((value, key) => (value == n…object

Immutably rename object keys

Return a copy with keys renamed through a mapping.

function renameKeys({ keysMap, object }) { return Object.fromEntries(Object.entries(object).map…object

Invert keys and values of an object

Swap every key with its value.

function invert(object) { return Object.fromEntries(Object.entries(object).map(([key, value]) =…object

Sort an object by its properties

Rebuild an object with its keys in sorted order.

function sortKeys(object) { return Object.fromEntries(Object.keys(object).sort().map(key => [ke…object

Shallow copy an object

Copy own enumerable properties into a new object.

function shallowCopy(object) { return { ...object }; }object

Get unique objects from an array by key

Keep one record per key value, the last one seen.

function uniqueBy({ objects, key }) { return [...new Map(objects.map(item => [item[key], item])…object

Get the total number of days in a year

Return 366 for Gregorian leap years and 365 otherwise.

function daysInYear(year) { return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0 ? 3…date & time

Set the time of a date to midnight

Return the start of the UTC day of a date-time.

function midnightUtc(now) { const d = new Date(now); d.setUTCHours(0, 0, 0, 0); return d.toISOS…date & time

Format a date for the given locale

Use Intl.DateTimeFormat with an explicit locale and time zone.

function formatDate({ date, locale }) { return new Intl.DateTimeFormat(locale, { timeZone: 'UTC…date & time

Get the current quarter of a date

Map the month to a quarter from 1 to 4.

function quarter(date) { return Math.ceil((new Date(date).getUTCMonth() + 1) / 3); }date & time

Get the day of the year from a date

Count days from January 1, which is day 1.

function dayOfYear(date) { return Math.round((Date.parse(date) - Date.parse(`${date.slice(0, 4)…date & time

Get the month name of a date

Look up the English month name of a date.

function monthName(date) { return ['January', 'February', 'March', 'April', 'May', 'June', 'Jul…date & time

Get the tomorrow date

Add one calendar day in UTC.

function tomorrow(date) { const d = new Date(date); d.setUTCDate(d.getUTCDate() + 1); return d.…date & time

Get the weekday of a date

Look up the English weekday name of a date.

function weekday(date) { return ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Frida…date & time

Sort an array of dates

Sort dates ascending or descending without changing the input.

function sortDates({ dates, order = 'asc' }) { const sorted = [...dates].sort((a, b) => Date.pa…date & time

Determine one year from a date

Add one to the UTC year.

function plusOneYear(date) { const d = new Date(date); d.setUTCFullYear(d.getUTCFullYear() + 1)…date & time

Get the number of days in a given month

Read day 0 of the next month for a 1-based month.

function daysInMonth({ year, month }) { const d = new Date(0); d.setUTCFullYear(year, month, 0)…date & time

Get the yesterday date

Subtract one calendar day in UTC.

function yesterday(date) { const d = new Date(date); d.setUTCDate(d.getUTCDate() - 1); return d…date & time

Get hours and minutes from decimal time

Split decimal hours into whole hours and whole minutes.

function hoursAndMinutes(value) { return [Math.floor(value), Math.floor((value * 60) % 60)]; }date & time

Convert hex to RGB

Expand #rgb if needed and read the red, green and blue channels.

function hexToRgb(hex) { return hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, (_, r, g, b) =>…misc

Convert URL parameters to object

Read a query string into an object; repeated keys become arrays.

function getUrlParams(query) { return Array.from(new URLSearchParams(query)).reduce((params, [k…misc

Convert Fahrenheit to Celsius

Subtract 32 and multiply by 5/9.

function fahrenheitToCelsius(fahrenheit) { return (fahrenheit - 32) * 5 / 9; }misc

Get the value of a param from a URL

Parse an absolute URL and read one query parameter.

function getParam({ url, param }) { return new URL(url).searchParams.get(param); }misc

Convert RGB color to hex

Pack three 0–255 channels into a #rrggbb string.

function rgbToHex({ red, green, blue }) { return `#${((1 << 24) + (red << 16) + (green << 8) + …misc

Convert cookie to object

Parse a Cookie header string into name–value pairs.

function parseCookies(cookie) { return Object.fromEntries(cookie.split(';').filter(item => item…misc

Easing functions

Evaluate a common easing curve at progress t between 0 and 1.

function ease({ name, t }) { return { linear: t, easeInQuad: t * t, easeOutQuad: t * (2 - t), e…misc

Encode a URL component strictly

Percent-encode a value, including !'()* that encodeURIComponent leaves alone.

function encodeStrict(value) { return encodeURIComponent(value).replace(/[!'()*]/g, char => `%$…misc

Get the value of a cookie

Find one cookie by name in a Cookie header string.

function getCookie({ cookie, name }) { const match = `; ${cookie}`.split(`; ${name}=`); return …misc

Get the type of a variable as a string

Read the internal [[Class]] tag via Object.prototype.toString.

function getTypeOf(value) { return Object.prototype.toString.call(value).match(/\[object (.*)\]…misc

Swap two variables

Exchange two values with array destructuring.

function swap([a, b]) { [a, b] = [b, a]; return [a, b]; }misc

Decode a JWT token

Read the JSON payload of a JSON Web Token — without verifying it.

function decodeJwtPayload(token) { const base64 = token.split('.')[1].replace(/-/g, '+').replac…misc

Get the first defined and non-null value

Return the first item that is neither null nor undefined.

function coalesce(values) { return values.find(item => item !== undefined && item !== null) ?? …misc

Convert a Lab color to an LCH color

Turn a and b into chroma and hue degrees.

function labToLch([l, a, b]) { return [l, Math.hypot(a, b), ((Math.atan2(b, a) * 180) / Math.PI…misc

Convert an LCH color to a Lab color

Turn chroma and hue degrees back into a and b.

function lchToLab([l, c, h]) { return [l, Math.cos((h * Math.PI) / 180) * c, Math.sin((h * Math…misc

Check if two DOMRects intersect

Two rects intersect when they meet on both axes.

function intersect({ a, b }) { return b.x <= a.x + a.width && b.x + b.width >= a.x && b.y <= a.…DOM

Get the center point of a DOMRect

Return [x, y] of the rect’s center.

function getCenter({ x, y, width, height }) { return [x + width / 2, y + height / 2]; }DOM

Logical xor operator

True when exactly one of two values is truthy.

function xor([a, b]) { return Boolean(a) !== Boolean(b); }function

Identity function

Return the argument unchanged.

function identity(value) { return value; }function

Get the domain of an email address

Take the part after the last @ and lowercase it, for domain checks and grouping.

function emailDomain(address) { return address.slice(address.lastIndexOf('@') + 1).toLowerCase(…email

Mask an email address for logs

Keep the first character and the domain; hide the rest of the local part.

function maskEmail(address) { return `${address.slice(0, 1)}•••${address.slice(address.lastInde…email

Normalize an email address for comparison

Trim whitespace and lowercase only the domain, preserving the local part.

function normalizeEmail(address) { const value = address.trim(); const at = value.lastIndexOf('…email

Read a Retry-After header

Turn delay-seconds or an HTTP date into milliseconds to wait, never negative.

function retryAfterMs({ retryAfter, date }) { const seconds = Number(retryAfter); return Math.m…email

Compute a backoff delay with full jitter

Double the window on every attempt, cap it, then pick a point inside it.

function backoffMs({ attempt, baseMs, capMs, random }) { return Math.round(random * Math.min(ca…email

Build an idempotency key from an event

Join a scope, a business id and a version into one stable, colon-separated key.

function idempotencyKey({ scope, id, version }) { return [scope, id, version].map(part => encod…email

Classify an SMTP reply

Read the reply code and enhanced status code, and tell a temporary failure from a permanent one.

function classifySmtpReply(reply) { const [, code, enhanced] = /^([2-5]\d{2})(?:[ -]([245]\.\d{…email

Build a DMARC record

Compose the TXT value for _dmarc.<domain> from a policy and an optional report address.

function dmarcRecord({ policy, rua }) { return ['v=DMARC1', `p=${policy}`, ...(rua ? [`rua=${ru…email

Parse a DMARC record

Split a published DMARC TXT value into its tags.

function parseDmarc(record) { return Object.fromEntries(record.split(';').map(tag => tag.trim()…email

Box handler

Chain transformations on a value, then unwrap the result.

function boxHandler(value) { return { next: f => boxHandler(f(value)), done: f => f(value) }; }…function

Check if a value is a function

True for anything callable: functions, arrows, async and generator functions, classes.

function isFunction(value) { return typeof value === 'function'; }function

Check if a value is a generator function

Read the internal tag of function* and async function* declarations.

function isGeneratorFunction(value) { return ['[object GeneratorFunction]', '[object AsyncGener…function

Check if a value is an async function

Read the internal tag of async function declarations and arrows.

function isAsyncFunction(value) { return Object.prototype.toString.call(value) === '[object Asy…function

Compose functions from left to right

Build one function that passes a value through each function in order.

function pipe(...fns) { return input => fns.reduce((value, fn) => fn(value), input); }function

Compose functions

Build one function that applies functions from right to left, as in f(g(x)).

function compose(...fns) { return input => fns.reduceRight((value, fn) => fn(value), input); }function

Curry a function

Collect arguments across calls until the function has as many as it declares.

function curry(fn, ...args) { return fn.length <= args.length ? fn(...args) : (...more) => curr…function

Delay the evaluation of a function

Turn a call into a thunk: a function that runs the call only when invoked.

function thunkify(fn) { return (...args) => () => fn(...args); }function

Execute a function once

Run a function on the first call and return that result afterwards.

function once(fn) { let done = false, result; return (...args) => { if (!done) { result = fn(..…function

Flip the arguments of a function

Call a function with its arguments in reverse order.

function flip(fn) { return (...args) => fn(...args.reverse()); }function

Memoize a function

Cache results by argument so each input is computed once.

function memoize(fn) { const cache = new Map(); return arg => { if (!cache.has(arg)) cache.set(…function

Partially apply a function

Fix the first arguments now and pass the rest later.

function partial(fn, ...preset) { return (...rest) => fn(...preset, ...rest); }function

Uncurry a function

Call a curried function with several arguments at once.

function uncurry(fn, depth = 1) { return (...args) => args.slice(0, depth).reduce((next, arg) =…function

Check if a value is a regular expression

Read the internal tag, which also works for values from another realm.

function isRegExp(value) { return Object.prototype.toString.call(value) === '[object RegExp]'; …validator

Check if an object is a Promise

Detect a thenable: an object or function with a then method.

function isPromise(value) { return value !== null && (typeof value === 'object' || typeof value…validator

Empty an array

Remove every item in place, so all references see an empty array.

function empty(values) { values.length = 0; return values; }array

Partition an array based on a condition

Split items into [matching, not matching] in one pass.

function partition(values, predicate) { return values.reduce((groups, value) => (groups[predica…array

Shuffle an array

Return a new array in random order, every order equally likely.

function shuffle(values) { const result = [...values]; for (let i = result.length - 1; i > 0; i…array

Get the timezone string

Read the runtime’s IANA time zone, such as America/Sao_Paulo.

function getTimezone() { return Intl.DateTimeFormat().resolvedOptions().timeZone; }date & time

Check if the code is running in Jest

Look for the JEST_WORKER_ID variable that Jest sets in its workers.

function isRunningInJest() { return typeof process !== 'undefined' && process.env.JEST_WORKER_I…misc

Clear all cookies

Expire every cookie that JavaScript can see on the current path.

function clearCookies() { for (const cookie of document.cookie.split(';')) { const name = cooki…misc

Detect dark mode

Read the prefers-color-scheme media feature.

function isDarkMode() { return window.matchMedia?.('(prefers-color-scheme: dark)').matches ?? f…misc

Emulate a dice throw

Return an integer from 1 to 6.

function throwDice() { return Math.floor(Math.random() * 6) + 1; }misc

Generate an unique and increment id

Create a counter that returns 0, 1, 2… on successive calls.

function createIdGenerator(start = 0) { let id = start; return () => id++; }misc

Run Promises in sequence

Start each task after the previous one finishes and collect the results in order.

async function runInSequence(tasks) { const results = []; for (const task of tasks) results.pus…misc

Wait for an amount of time

Return a promise that resolves after the given milliseconds.

function wait(milliseconds) { return new Promise(resolve => setTimeout(resolve, milliseconds));…misc

Wait for the next event loop

Resolve after the current task, letting queued timers, I/O and rendering run.

function nextTask() { return new Promise(resolve => setTimeout(resolve, 0)); }misc

Generate a random boolean

Return true or false with equal probability.

function randomBoolean() { return Math.random() < 0.5; }random

Generate a random hex color

Return a #rrggbb color from 24 random bits.

function randomColor() { return `#${Math.floor(Math.random() * 0x1000000).toString(16).padStart…random

Generate a random IP address

Return a random IPv4 address from the ranges reserved for documentation.

function randomDocumentationIp() { const networks = ['192.0.2', '198.51.100', '203.0.113']; ret…random

Generate a random sign

Return 1 or -1 with equal probability.

function randomSign() { return Math.random() < 0.5 ? -1 : 1; }random

Generate a random string from given characters

Draw characters from an alphabet with a cryptographic generator, without bias.

function randomString(length, alphabet) { if (alphabet.length < 2 || alphabet.length > 256) thr…random

Generate a random string with given length

Return a lowercase Base32 identifier from a cryptographic generator.

function randomId(length) { const alphabet = '0123456789abcdefghjkmnpqrstvwxyz'; return Array.f…random

Generate a random UUID

Return a version 4 UUID from the platform’s cryptographic generator.

function uuid() { return crypto.randomUUID(); }random

Get a random item from an array

Return one item at a random index.

function randomItem(values) { return values[Math.floor(Math.random() * values.length)]; }random

Get random items of an array

Return count distinct items in random order.

function randomItems(values, count) { const pool = [...values]; for (let i = pool.length - 1; i…random

Pick a random property of an object

Return one of the object’s own enumerable keys.

function randomKey(object) { const keys = Object.keys(object); return keys[Math.floor(Math.rand…random

Pick random lines from a text document

Split text into lines and return count of them in random order.

function randomLines(text, count) { const lines = text.split(/\r?\n/); for (let i = lines.lengt…random

Check if an element has CSS overflow

True when either axis is styled to scroll: overflow auto or scroll.

function hasCssOverflow(element) { const { overflowX, overflowY } = getComputedStyle(element); …DOM

Check if an element has overflow

True when the content is larger than the element’s visible box.

function hasOverflow(element) { return element.scrollHeight > element.clientHeight || element.s…DOM

Check if an element is focused

Compare the element with document.activeElement.

function hasFocus(element) { return element === document.activeElement; }DOM

Check if the touch events are supported

True when the browser exposes touch events or reports touch points.

function touchSupported() { return 'ontouchstart' in window || navigator.maxTouchPoints > 0; }DOM

Detect Internet Explorer browser

Look for document.documentMode, which only Internet Explorer defines.

function isInternetExplorer() { return 'documentMode' in document; }DOM

Detect macOS browser

Guess whether the device is a Mac, iPhone or iPad from the platform string.

function isApplePlatform() { return /Mac|iPhone|iPad|iPod/.test(navigator.userAgentData?.platfo…DOM

Get all siblings of an element

Return the other element children of the element’s parent.

function siblings(element) { return element.parentElement ? [...element.parentElement.children]…DOM

Get the selected text

Read the text of the current document selection.

function getSelectedText() { return window.getSelection()?.toString() ?? ''; }DOM

Hide an element

Set the hidden attribute.

function hide(element) { element.hidden = true; }DOM

Insert given HTML after an element

Parse an HTML string and insert it after the element.

function insertHtmlAfter(html, element) { element.insertAdjacentHTML('afterend', html); }DOM

Insert given HTML before an element

Parse an HTML string and insert it before the element.

function insertHtmlBefore(html, element) { element.insertAdjacentHTML('beforebegin', html); }DOM

Redirect to another page

Navigate to a URL, adding an entry to the history.

function goTo(url) { location.assign(url); }DOM

Replace an element

Swap an element for another in the same position.

function replace(element, replacement) { element.replaceWith(replacement); }DOM

Serialize form data

Turn a form’s fields into an object; repeated names become arrays.

function serialize(form) { const groups = new Map(); for (const [key, value] of new FormData(fo…DOM

Show an element

Clear the hidden attribute and any inline display: none.

function show(element) { element.hidden = false; element.style.removeProperty('display'); }DOM

Strip HTML from a given text

Parse HTML in an inert document and return its text.

function stripHtml(html) { return new DOMParser().parseFromString(html, 'text/html').body.textC…DOM

Toggle an element

Flip the hidden attribute.

function toggle(element) { element.hidden = !element.hidden; }DOM

Want every function on one page? Print the one-line sheet. Looking for an application rather than a function? Browse integration recipes.

Type two or more characters. Try “duplicate”, “webhook” or “retry”.