Skip to content

Strings

Casing, trimming, replacement, padding, slugify, truncate, mask, template, HTML helpers, Arabic detection. Import from @mongez/reinforcements.

Casing — powered by words()

All casing functions share a single tokenizer that handles acronyms correctly.

words

words(input: string): string[]
words("XMLHttpRequest"); // ["XML", "Http", "Request"]
words("AIAgent"); // ["AI", "Agent"]
words("hello-world"); // ["hello", "world"]

Casing family

FunctionSignatureExample
toCamelCase(str) => stringtoCamelCase("XMLHttpRequest")"xmlHttpRequest"
toStudlyCase(str) => stringtoStudlyCase("hello-world")"HelloWorld"
toPascalCase(str) => stringAlias of toStudlyCase
toSnakeCase(str, separator?, lowerAll?) => stringtoSnakeCase("AIAgent")"ai_agent"
toKebabCase(str, lowerAll?) => stringtoKebabCase("getUserID")"get-user-id"
toConstantCase(str) => stringtoConstantCase("apiBaseUrl")"API_BASE_URL"
toDotCase(str, lowerAll?) => stringtoDotCase("helloWorld")"hello.world"
toPathCase(str, lowerAll?) => stringtoPathCase("helloWorld")"hello/world"
toTitleCase(str, options?: { stopWords? }) => stringtoTitleCase("the lord of rings")"The Lord of Rings"

Letter case primitives

ucfirst(str: string): string // uppercase first char
capitalize(str: string): string // ucfirst on every whitespace-separated word
ucfirst("hello"); // "Hello"
capitalize("hello world"); // "Hello World"

Trimming

FunctionSignatureNotes
trim(str, needle?: string) => stringTrims both ends (default whitespace)
ltrim(str, needle?: string) => stringStart only
rtrim(str, needle?: string) => stringEnd only
trim(" hi "); // "hi"
trim("---hi---", "-"); // "hi"
ltrim("//path", "/"); // "path"
rtrim("file.tmp", ".tmp"); // "file"

Replacement family

replaceAll(str, search, replacement): string
replaceFirst(str, search, replacement): string
replaceLast(str, search, replacement): string
removeFirst(str, needle): string // = replaceFirst(str, needle, "")
removeLast(str, needle): string // = replaceLast(str, needle, "")

search/needle are literal strings — they’re regex-escaped internally.

replaceAll("a-b-c", "-", "_"); // "a_b_c"
replaceFirst("foo foo foo", "foo", "bar"); // "bar foo foo"
replaceLast("foo bar foo", "foo", "baz"); // "foo bar baz"

repeatsOf

repeatsOf(str: string, needle: string, caseSensitive?: boolean): number // default true
repeatsOf("abcabc", "a"); // 2
repeatsOf("AbcAbc", "a", false); // 2

Padding

pad(str, length, char?): string // pad both sides; extra char goes to end
padStart(str, length, char?): string // typed wrapper around String#padStart
padEnd(str, length, char?): string // typed wrapper around String#padEnd
pad("hi", 6); // " hi "
pad("hi", 7, "*"); // "**hi***"
padStart("7", 3, "0"); // "007"
padEnd("7", 3, "0"); // "700"

URL slugs & truncation

slugify

slugify(str, options?: {
separator?: string; // default "-"
lower?: boolean; // default true
strict?: boolean; // default true — strip non-alphanumeric per token
}): string
slugify("Hello, World!"); // "hello-world"
slugify("café crème"); // "cafe-creme"
slugify("Hello World", { separator: "_" }); // "hello_world"

truncate

truncate(str, length, options?: {
suffix?: string; // default "..."
byWord?: boolean; // default false — cut at word boundary
position?: "end" | "middle"; // default "end"
}): string
truncate("hello world", 8); // "hello..."
truncate("hello world there", 14, { byWord: true }); // "hello world..."
truncate("abcdefghij", 7, { position: "middle" }); // "ab...ij"

readMoreChars / readMoreWords

readMoreChars(str, length, suffix?: string): string // default suffix "..."
readMoreWords(str, wordCount, suffix?: string): string
readMoreChars("hello world", 5); // "hello..."
readMoreWords("a b c d e", 3); // "a b c..."

HTML & masking

escapeHtml / unescapeHtml

escapeHtml(str: string): string // & < > " ' → entities
unescapeHtml(str: string): string // reverse
escapeHtml('<a href="x">'); // "&lt;a href=&quot;x&quot;&gt;"

stripHtmlTags

stripHtmlTags(str, options?: {
replacement?: string; // default ""
stripScriptsAndStyles?: boolean; // default true — drops content too
stripComments?: boolean; // default true
}): string

Not a sanitizer — for untrusted HTML, use DOMPurify.

stripHtmlTags("<p>Hello <b>world</b></p>"); // "Hello world"
stripHtmlTags("<script>alert(1)</script>safe"); // "safe"
stripHtmlTags("<p>hi</p>", { replacement: " " }); // " hi "

mask

mask(str, options?: {
start?: number; // visible chars from start, default 0
end?: number; // visible chars from end, default 0
char?: string; // mask char, default "*"
}): string
mask("4242424242424242", { start: 0, end: 4 }); // "************4242"
mask("hassan@gmail.com", { start: 2, end: 4 }); // "ha**********.com"

Templates

template

template(str: string, vars: Record<string, any>): string

{path} interpolation with dot-notation paths into vars. Missing paths render as "".

template("Hello {user.name}!", { user: { name: "Ada" } });
// "Hello Ada!"
template("{count} items", { count: 3 });
// "3 items"

Counting & reversal

wordCount(str: string): number
charCount(str: string, options?: { unicode?: boolean }): number // grapheme-aware when true
reverse(str: string): string // unicode-safe (handles surrogate pairs)
wordCount("hello world"); // 2
charCount("hello"); // 5
charCount("👨‍👩", { unicode: true }); // 1 (single grapheme)
reverse("hello"); // "olleh"

Misc

initials

initials(name: string, separator?: string): string // default separator ""
initials("Ada Lovelace"); // "AL"
initials("Ada Lovelace", "."); // "A.L"

extension

extension(filename: string): string

Returns the part after the last dot, or "" if absent.

extension("foo.txt"); // "txt"
extension("archive.tar.gz"); // "gz"
extension("README"); // ""

toInputName

toInputName(path: string): string

"a.b.c""a[b][c]" for HTML form name attributes.

toInputName("user.address.city"); // "user[address][city]"
toInputName("user.tags[]"); // "user[tags][]"

Arabic

startsWithArabic(str: string, trimmed?: boolean): boolean // default trimmed = true
containsArabic(str: string): boolean
ARABIC_REGEX: RegExp // /[؀-ۿ]/
ARABIC_PATTERN: RegExp // @deprecated — same as ARABIC_REGEX
startsWithArabic("مرحبا"); // true
startsWithArabic(" مرحبا"); // true (trimmed)
containsArabic("hello مرحبا"); // true