Helpers (v3+)

Optional modules beyond types, regex, and validate. Tree-shake by importing only the subpaths you need: helping-js/core/<module>.

Module docs (samples on each page)

Doc pagenpm import
Numberhelping-js/core/number
Stringhelping-js/core/string
Valuehelping-js/core/value
Arrayhelping-js/core/array
Objecthelping-js/core/object
Functionhelping-js/core/function
Asynchelping-js/core/async
URLhelping-js/core/url
Datehelping-js/core/date
Advancedhelping-js/core/advanced
Treehelping-js/core/tree
DOMhelping-js/core/dom (browser)

Module overview (source)

SubpathWhat it gives you
core/numberopen in new windowrandInt, randChoice, between, notLessThan, notGreaterThan, strPad
core/stringopen in new windowcamelCase, kebabCase, snakeCase, studlyCase, titleCase, camelToWords, randString, reverseString
core/valueopen in new windowisEmptyValue — treats null, undefined, '', [], {}, false, 0, NaN as empty
core/arrayopen in new windowarrayRemove, arrayDiff, splitArray, groupArray, arrayDistinct, arrayFlat, toArrayIfNot, …
core/objectopen in new windowdotGet, dotSet (blocks __proto__ / constructor / prototype paths), objectOnly, objectExcept, cloneObject, …
core/functionopen in new windowresolveValueOrGetter, bindContext, mapObjectTree, composition helpers
core/asyncopen in new windowdebounceTrailing, debounceImmediate, retry, promiseTimeout, executePromiseGetters, …
core/urlopen in new windowpathJoin (Node-safe), getUrlParam (optional URL string or current page in the browser)
core/dateopen in new windowcloneDate, addDate, getMonthStart / getMonthEnd, getCalendar, parseISO, isIsoFormat
core/advancedopen in new windowbinarySearch, Cache, ArrayKeyMap, attachCache, easeInOutQuad, windowLoaded, …
core/treeopen in new windowwalkTreeData, TreeData with safe clone()
core/domopen in new windowBrowser onlyon, off, addClass, viewportPositionToFixed, … Do not import in pure Node SSR bundles.

Naming conflicts with other libraries: core/types keeps existing semantics (isNumber, isNumeric, …). See HELPER_INVENTORY.mdopen in new window.


Minimal examples

import { strPad, between } from 'helping-js/core/number'
import { kebabCase } from 'helping-js/core/string'
import { dotSet, dotGet } from 'helping-js/core/object'
import { isEmptyValue } from 'helping-js/core/value'

const state = {}
dotSet(state, 'user.profile.id', 42)
console.log(kebabCase('FooBar'))       // 'foo-bar'
console.log(strPad('7', 3, '0'))        // '007'
console.log(between(150, 0, 100))      // 100
console.log(isEmptyValue(state.user)) // false

Vue 3 (Composition API)

Debounce user input, format labels, and read nested config with dotGet:

<script setup>
import { ref, watch } from 'vue'
import { debounceTrailing } from 'helping-js/core/async'
import { titleCase } from 'helping-js/core/string'
import { dotGet } from 'helping-js/core/object'

const props = defineProps({ config: Object })
const query = ref('')
const heading = ref('')

const runSearch = debounceTrailing((q) => {
  heading.value = titleCase(q.trim() || 'search')
  // e.g. call API with q
}, 300)

watch(query, (v) => runSearch(v))

const apiBase = () => dotGet(props.config, 'api.baseUrl')
</script>

React (hooks)

Memoize derived data with array/object helpers:

import { useMemo, useState } from 'react'
import { arrayDistinct, splitArray } from 'helping-js/core/array'
import { objectOnly } from 'helping-js/core/object'

export function TagList({ items }) {
  const [page, setPage] = useState(0)
  const unique = useMemo(() => arrayDistinct(items), [items])
  const pages = useMemo(() => splitArray(unique, 10), [unique])
  const slice = pages[page] ?? []

  return (
    <ul>
      {slice.map((id) => (
        <li key={id}>{id}</li>
      ))}
    </ul>
  )
}

// Pick a subset of props for a child
export function passThemeProps(full) {
  return objectOnly(full, ['mode', 'density'])
}

Express (Node)

Join path segments safely and reuse type helpers in middleware:

const express = require('express')
const path = require('path')
const { pathJoin } = require('helping-js/core/url')
const { isString } = require('helping-js/core/types')

const app = express()
const publicDir = pathJoin(__dirname, 'public')

app.use(express.static(publicDir))

app.get('/health', (req, res) => {
  const tag = req.query.tag
  if (tag != null && !isString(tag)) {
    return res.status(400).json({ error: 'tag must be a string' })
  }
  res.json({ ok: true })
})

pathJoin normalizes slashes for URL-like segments; for filesystem paths you can still use path.join from Node — use whichever fits the use case.


Browser-only (core/dom)

Import only in client code (Vite import.meta.env.SSR, Next.js 'use client', or Vue client components):

import { on, addClass } from 'helping-js/core/dom'

const el = document.querySelector('#app')
if (el) {
  addClass(el, 'is-ready')
  const un = on(el, 'click', () => {
    console.log('clicked')
    un()
  })
}

See also

Last Updated:
Contributors: parsajiravand