@rtorcato/js-common
v4.0.0
Published
JavaScript and TypeScript common code
Readme
js-common
A comprehensive set of common JavaScript and TypeScript utilities for Node.js projects.
📘 Documentation: https://rtorcato.github.io/js-common/
Features
- Tree-shakeable — import only what you need via subpath exports
- TypeScript — full type definitions, JSDoc on every public API
- CLI included — optional binary for use in scripts and terminals
- Modular — one module per concern, 42 subpaths
- Minimal runtime deps — only
pino,uuid,short-uuid,zod. CLI packages (chalk,commander,figlet, …) areoptionalDependenciesand only needed for the CLI.
Installation
npm install @rtorcato/js-commonPre-release builds are published to the beta dist-tag, so they never reach a plain npm install:
npm install @rtorcato/js-common@betaUse with AI
An agent skill lives in skills/js-common — it teaches an AI coding agent the subpath-import rules, which same-named helper belongs to which module, the three error idioms, which modules are Node-only, and the full module → exports map.
Claude Code — this repo is its own plugin marketplace:
/plugin marketplace add rtorcato/js-common
/plugin install js-common@js-commonCursor, Copilot, Codex and other tools — read AGENTS.md, the cross-tool convention file. It carries the same guidance and also ships in the npm tarball, so tools that scan node_modules find it at node_modules/@rtorcato/js-common/AGENTS.md.
Any tool the skills CLI supports:
npx skills add https://github.com/rtorcato/js-common --skill js-commonAGENTS.md is generated from SKILL.md by pnpm sync:agents; CI fails if they drift. Edit SKILL.md, never AGENTS.md.
Migrating
3.x → 4.x — everything the runtime already does was removed. ./sets and ./interval are gone as modules, and the pass-through wrappers inside surviving modules went with them: promises.all/allSettled/race/delay, boolean.and/or/not/xor, strings.padStart/padEnd/replaceString, arrays.first/last/flatten/groupBy, numbers.isInteger/isFiniteNumber/min/max, objects.deepClone, json.deepCloneJson and uuid.getUUID. Nothing moved to another module — the replacement is a JavaScript built-in in every case, which the Node 22 floor guarantees. Two are not drop-ins: Object.groupBy returns a null-prototype object with optional values, and structuredClone keeps Dates where the JSON round trip flattened them. The full before/after table is in the migration guide.
2.x → 3.x — every helper now has exactly one home. ./formatting and ./math are gone, and where two modules shipped the same name the loser was deleted rather than aliased, so you get a build error naming the fix. One helper was also renamed rather than moved: sanitizeString is now stripScriptish, because the old name promised sanitising it never did — it removes <script> blocks and inline on* handlers and nothing else. The full before/after map is in the migration guide; the reasoning is in MODULE-BOUNDARIES.md.
1.x → 2.x — the only breaking change in 2.0 is a rename in the errors module:
// boundary-check: ignore — quotes the pre-2.0 API on purpose
// 1.x — swallow errors and fall back to a default value
import { tryCatch } from '@rtorcato/js-common/errors'
const data = await tryCatch(() => fetchData(), [])
// 2.x — same function, renamed for clarity
import { tryWithFallback } from '@rtorcato/js-common/errors'
const data = await tryWithFallback(() => fetchData(), [])The name tryCatch is now reserved for the Result-pattern helper in @rtorcato/js-common/try, which returns { data, error } instead of swallowing:
import { tryCatch } from '@rtorcato/js-common/try'
const { data, error } = await tryCatch(() => fetchData())
if (error) { /* handle */ }Prefer the Result-style tryCatch for new code; reserve tryWithFallback for cases where the fallback is genuinely safe.
CLI Usage
This package includes a command-line interface for many utilities:
# Install globally to use the CLI
npm install -g @rtorcato/js-common
# Or use with npx
npx @rtorcato/js-common@latest --help
# Examples
npx @rtorcato/js-common@latest date today
npx @rtorcato/js-common@latest math sum 1 2 3 4 5
npx @rtorcato/js-common@latest text capitalize "hello world"
npx @rtorcato/js-common@latest system node-versionSee CLI.md for complete CLI documentation.
Library Usage
// Import specific modules (recommended for tree-shaking)
import { formatDate, today, daysBetween } from '@rtorcato/js-common/date'
import { isValidEmail, normalizeEmail } from '@rtorcato/js-common/emails'
import { getUUIDv7, isUUID } from '@rtorcato/js-common/uuid'
import { sum, average, roundTo } from '@rtorcato/js-common/numbers'
import { capitalize, titleCase } from '@rtorcato/js-common/strings'
// Example usage
console.log(today()) // "2026-05-29"
console.log(sum([1, 2, 3, 4, 5])) // 15
console.log(capitalize('hello world')) // "Hello world"
console.log(getUUIDv7()) // "018e5e2c-7c0a-7000-8000-0e02b2c3d479"Bundle Size Impact
Each module is shipped as its own subpath export so bundlers only include what you import. Individual modules range from ~100 bytes (e.g. sleep) to ~2 KB (e.g. currency) when minified. Measure against your own bundle with bundlejs.com.
Available Modules
Which module a helper belongs to — and why no helper is exported from two of them — is recorded in MODULE-BOUNDARIES.md. These paths are frozen as of that record.
Date & Time
import { today, formatDate, daysBetween, isLeapYear } from '@rtorcato/js-common/date'
import { nowIso, formatDateTimeLocal, unixTimestamp } from '@rtorcato/js-common/datetime'
import { nowTime, parseTime, secondsBetween } from '@rtorcato/js-common/time'Numbers
import { sum, average, roundTo, clamp, formatPercent } from '@rtorcato/js-common/numbers'
import { randomInt, randomFloat, randomBool, randomElement } from '@rtorcato/js-common/random'Text & Strings
import { slugify, truncate, capitalize, titleCase, pluralize } from '@rtorcato/js-common/strings'
import { escapeHtml, unescapeHtml, stripHtmlTags } from '@rtorcato/js-common/html'
import { escapeRegExp, matchAll, replaceAllRegex } from '@rtorcato/js-common/regex'
import { detectLanguage, formatNumber, formatDateI18n, t } from '@rtorcato/js-common/i18n'Security & Validation
import { isStrongPassword, generateSecureToken } from '@rtorcato/js-common/security'
import { isValidEmail, maskEmail } from '@rtorcato/js-common/emails'
import { isValidUrl } from '@rtorcato/js-common/url'
import { isString, isNumber, isBoolean, isArray, isObject } from '@rtorcato/js-common/validation'
import { toBoolean } from '@rtorcato/js-common/boolean'Data Structures
import { unique, chunk, compact, shuffle } from '@rtorcato/js-common/arrays'
import { deepMerge, pick, omit, isPlainObject } from '@rtorcato/js-common/objects'
import { safeJsonParse, safeJsonStringify } from '@rtorcato/js-common/json'
import { invertMap, mapValues, objectToMap, mapToObject } from '@rtorcato/js-common/maps'Async & Control Flow
import { to, withTimeout } from '@rtorcato/js-common/promises'
import { debounce, throttle, once } from '@rtorcato/js-common/functions'
import { sleep } from '@rtorcato/js-common/sleep'
import { tryCatch } from '@rtorcato/js-common/try'
import { createAbortController, withAbort, abortAfter } from '@rtorcato/js-common/abortController'
import { createCustomError, getErrorMessage, assert } from '@rtorcato/js-common/errors'System & Process
import { getENV, isDev, isProd, getNodeEnv, checkEnv } from '@rtorcato/js-common/env'
import { getOsPlatform, getOsArch, getHomeDir } from '@rtorcato/js-common/os'
import { getNodeMajorVersion, isNode, requireOptional } from '@rtorcato/js-common/node'
import { getProcessId, getCwd, exitProcess, isCI } from '@rtorcato/js-common/process'
import { isMacOs, isWindows, isLinux, getPlatform } from '@rtorcato/js-common/system'
import { disableConsole, clearConsole } from '@rtorcato/js-common/console'Logging
import { logger } from '@rtorcato/js-common/logger' // pino-based
import { info, warn, error, captureConsole } from '@rtorcato/js-common/logging'Other
colors— color manipulation and conversioncrypto— cryptographic helperscurrency— currency formatting and conversionevents— DOM event helpers (on,emit,onceEvent)fetch— HTTP request helpersfile— file system helpersgeometry— 2D geometry calculationsmime-types— MIME-type lookupuuid— UUID generation and validationtypes— shared TypeScript type definitions (types-only export)
Requirements
- Node.js >= 22.0.0 (enforced via the
enginesfield) - TypeScript >= 5.0.0 (for TypeScript projects)
Development
# Install dependencies
pnpm install
# Run tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Build the project
pnpm run build-prod
# Build development version
pnpm run build-dev
# Lint and format
pnpm run check:fix
# Type checking
pnpm run typecheck
# Run micro-benchmarks (scripts/benchmark.mjs)
pnpm run benchmarkDocumentation site
The full documentation site lives in apps/docs and is built with Docusaurus. It auto-deploys to GitHub Pages on every push to main that touches apps/docs/**.
# Run the docs locally (http://localhost:3000/js-common/)
pnpm --filter @rtorcato/js-common-docs dev
# Build the static site
pnpm --filter @rtorcato/js-common-docs buildLive site: https://rtorcato.github.io/js-common/
Roadmap
Direction and progress are tracked entirely on GitHub — see the milestones for the stages (shipped 2.x modules, the beta npm preview, the v1.0 stable API) and the open issues for day-to-day work.
Contributing
Contributions are welcome! Please read CONTRIBUTORS.md for guidelines.
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Make your changes with tests
- Run the test suite:
pnpm test - Submit a pull request
Related packages
- @rtorcato/browser-common — Browser Web API wrappers (clipboard, observers, storage, etc.)
- @rtorcato/repo-tooling — Project scaffolding for TypeScript libraries (Biome, Vitest, Husky, semantic-release)
License
MIT © Richard Torcato
