A comprehensive TypeScript/JavaScript library for procedural natural language generation, string manipulation, and grammatical inflection. Originally built to provide utility functions for producing natural-sounding English from component parts, it's perfect for text generators, game development, and formatting data seamlessly.
Full documentation is available at ironarachne.github.io/words.
npm install @ironarachne/wordsThe library is organized into specialized domains for all your procedural text needs:
Easily change string formats for code, IDs, or display.
capitalize,uncapitalize,title(Title Case)camelCase,snakeCase,kebabCase,swapCase
Helpers for assembling dynamic sentences to keep your procedural text grammatically correct.
- Articles & Pronouns: Generate the correct article (
a/an) or pronoun based on gender and context. - Quantification:
quantify(2, "apple")->"2 apples" - Verbs & Copulas:
isAre(count),hasHave(count),wasWere(count)to match plurals automatically. - Possessives: Properly format nouns (e.g.,
possessive("James")->"James'",possessive("dog")->"dog's").
Robust rules and an expansive irregular dictionary (e.g., radius/radii, goose/geese, deer).
pluralize(word: string)singularize(word: string)detectPlural(word: string)comparative(word: string)->"big"becomes"bigger","beautiful"becomes"more beautiful"superlative(word: string)->"big"becomes"biggest","beautiful"becomes"most beautiful"
Format numbers as text or traditional numeric formats.
getOrdinal(1)->"1st"ordinalWord(1)->"first"numberToWords(21)->"twenty-one"romanize(4)->"IV"
Create clean paragraphs, phrases, and text elements.
- Sentence Building:
buildSentence(parts)automatically capitalizes and fixes terminal punctuation. - Lists:
arrayToPhrase(["apple", "banana"], "or")->"apple or banana" - Punctuation:
fixPunctuation(text)fixes double-spaces, space-before-comma, and duplicate punctuation. - Formatting:
slugify,truncateWords,squish,stripPunctuation - Metrics:
wordCount,readingTime
Building grammatically accurate procedural sentences is simple:
import { quantify, isAre, arrayToPhrase, buildSentence } from "@ironarachne/words";
const enemyCount = 3;
const enemyType = "goblin";
const loot = ["gold coin", "rusty dagger"];
// "3 goblins"
const enemies = quantify(enemyCount, enemyType);
// "are"
const copula = isAre(enemyCount);
// "gold coin and rusty dagger"
const lootPhrase = arrayToPhrase(loot);
const parts = [
"there", copula, enemies, "guarding the", lootPhrase
];
// Returns: "There are 3 goblins guarding the gold coin and rusty dagger."
const text = buildSentence(parts);
console.log(text);This project uses TypeScript, Vitest for testing, and Biome for linting and formatting. Node 20 or newer is required.
# Install dependencies
npm install
# Lint, build, and test — run this before pushing
npm run checkmain is protected; every change lands through a pull request with CI green.
See CONTRIBUTING.md for the full workflow and how releases
are cut, and CODE_STYLE.md for the conventions this codebase
follows.
MIT License.