humanize-list
Joins JavaScript arrays into natural, comma-separated English text with an optional Oxford comma and custom conjunctions.
Repository Health
Technical Analysis
humanize-list is a small, dependency-free npm utility that turns an array like ['apples', 'tomatoes', 'unicorns'] into a natural-reading string such as “apples, tomatoes and unicorns”. It handles the punctuation edge cases developers otherwise hand-roll themselves — single-item lists, the placement of the final conjunction, and whether to include the Oxford comma before it.
The entire library is a single exported function that accepts an array and an options object (oxfordComma, conjunction, skipConjunction), making it trivial to drop into UI copy, error messages, or notification text wherever a list of items needs to read like a sentence rather than a raw array dump.
What You Get
- A single, zero-dependency function (
humanizeList) importable via CommonJSrequire - Automatic correct handling of the single-item-list edge case (returns the item with no punctuation)
- An
oxfordCommaoption to control whether a comma precedes the final conjunction - A
conjunctionoption to swap ‘and’ for ‘or’ or any custom word - A
skipConjunctionoption to fall back to a plain comma-delimited list
Common Use Cases
- Rendering a friendly summary of selected filters or tags in a UI (“Showing results for React, Vue and Svelte”)
- Building human-readable error messages that list invalid or missing fields
- Generating notification or email copy that references multiple items by name
- Formatting search facets or comma-separated metadata for display instead of raw arrays
Under The Hood
Architecture
The entire library is a single CommonJS module (index.js, ~26 lines) exporting one pure function, humanizeList(list, options). There is no internal layering, no dependency injection, and no external state — input validation happens first via an Array.isArray check that throws a TypeError with a descriptive message, followed by a straightforward for loop that builds the output string by tracking whether the current index is the first, last, or a middle element. Because the module has exactly one file, zero runtime dependencies, and one exported entry point, there is nothing else in the codebase that a change to the core loop could break other than that function’s own callers.
Tech Stack
Written in plain ES5-style JavaScript (var, 'use strict') with zero runtime dependencies declared in package.json. The only devDependency is ava (^0.8.0) for testing; tests import the module via ES module import syntax, relying on ava’s internal Babel transform rather than a project-level build step. There is no bundler, no TypeScript, and no transpilation pipeline for the library code itself — it ships exactly as authored. CI was configured via a .travis.yml file targeting Travis CI, a service that has since been largely superseded industry-wide.
Code Quality
A test.js suite using ava covers five behavioral cases: the standard multi-item join, the single-item edge case, the Oxford-comma variant, a custom conjunction, and the conjunction-skipping mode — solid coverage relative to the function’s small surface area. There are no type annotations or TypeScript definitions, so consumers get no compile-time safety on the options shape. A .jshintrc is present for linting via JSHint, an older and now largely unmaintained linting tool, and there’s no evidence of an active, currently-running CI pipeline (Travis CI’s free tier for open source was discontinued years after this project’s last commit).
What Makes It Unique
There is no genuinely novel technical mechanism here — humanize-list predates the standardized Intl.ListFormat API (broadly available in browsers and Node since around 2020) and essentially hand-rolls the same list-humanization behavior that API now provides natively. Its value is purely historical convenience and a slightly different options shape (oxfordComma, skipConjunction) rather than any architectural or algorithmic innovation.