String
Utilities for transforming and validating strings. Import from the root or from koyojs/String.
// Root import
import { capitalize, slugify, isEmail } from "koyojs";
// Per-module import
import { capitalize } from "koyojs/String";Capitalizes the first character of a string, leaving the rest unchanged.
| Parameter | Type | Description |
|---|---|---|
input | string | The input string. |
| returns | string | — |
import { capitalize } from "koyojs";
capitalize("hello world"); // "Hello world"
capitalize("javaScript"); // "JavaScript"
capitalize(""); // ""
// Note: only the very first character is changed — the rest stays as-is
capitalize("hELLO"); // "HELLO"
// Common use: format a user's display name from a form field
const name = capitalize(user.firstName.trim());Converts a string with spaces, hyphens, or underscores to camelCase.
| Parameter | Type | Description |
|---|---|---|
input | string | The input string. |
| returns | string | — |
import { toCamelCase } from "koyojs";
toCamelCase("hello world"); // "helloWorld"
toCamelCase("my-variable"); // "myVariable"
toCamelCase("some_prop_name"); // "somePropName"
toCamelCase("--weird input_"); // "weirdInput"
// Transform snake_case API response keys to camelCase for JS
const apiResponse = { user_id: 1, first_name: "Alice", is_admin: false };
const camel = Object.fromEntries(
Object.entries(apiResponse).map(([k, v]) => [toCamelCase(k), v])
);
// { userId: 1, firstName: "Alice", isAdmin: false }Converts a string to snake_case — all lowercase with words separated by underscores.
| Parameter | Type | Description |
|---|---|---|
input | string | The input string. |
| returns | string | — |
import { toSnakeCase } from "koyojs";
toSnakeCase("Hello World"); // "hello_world"
toSnakeCase("myVariable"); // "my_variable"
toSnakeCase("camelCaseKey"); // "camel_case_key"
toSnakeCase("already_snake"); // "already_snake"
// Serialize JS camelCase keys to snake_case for a REST API payload
const body = { firstName: "Alice", maxResults: 10, includeDeleted: false };
const snakeBody = Object.fromEntries(
Object.entries(body).map(([k, v]) => [toSnakeCase(k), v])
);
// { first_name: "Alice", max_results: 10, include_deleted: false }Converts a string to Title Case — first letter of each word capitalized.
| Parameter | Type | Description |
|---|---|---|
input | string | The input string. |
| returns | string | — |
import { toTitleCase } from "koyojs";
toTitleCase("hello world"); // "Hello World"
toTitleCase("the quick brown fox"); // "The Quick Brown Fox"
toTitleCase("already Title Case"); // "Already Title Case"
// Render a blog post title stored in lowercase
const post = { title: "getting started with solidjs and vite" };
<h1>{toTitleCase(post.title)}</h1>
// "Getting Started With Solidjs And Vite"
// Format category labels coming from a database
const category = "science_and_technology";
toTitleCase(category.replace(/_/g, " "));
// "Science And Technology"Converts a string into a URL-friendly slug — lowercase, spaces replaced with hyphens, special characters and diacritics removed.
| Parameter | Type | Description |
|---|---|---|
input | string | The input string. |
| returns | string | — |
import { slugify } from "koyojs";
slugify("Hello World!"); // "hello-world"
slugify("My Blog Post Title #1"); // "my-blog-post-title-1"
slugify(" extra spaces "); // "extra-spaces"
slugify("Déjà vu!"); // "deja-vu"
// Generate a permalink from a post title
const post = { title: "10 Tips for Writing Clean TypeScript" };
const url = `/blog/${slugify(post.title)}`;
// "/blog/10-tips-for-writing-clean-typescript"
// Build a URL-safe product ID
const product = { name: "Wireless Headphones Pro (2025 Edition)" };
const path = `/products/${slugify(product.name)}`;
// "/products/wireless-headphones-pro-2025-edition"Hard-cuts a string to at most maxLength characters. No ellipsis is added — the string is simply sliced at that position. Throws a RangeError if maxLength is negative. Use `ellipsify` if you want a trailing "..." appended automatically.
| Parameter | Type | Description |
|---|---|---|
input | string | The input string. |
maxLength | number | Maximum number of characters to keep. Must be ≥ 0. |
| returns | string | — |
import { truncate } from "koyojs";
truncate("Hello, World!", 8); // "Hello, W"
truncate("Short", 10); // "Short" — already fits, returned as-is
truncate("", 5); // ""
// Enforce a database column length before INSERT
const bio = "This is a very long biography that goes on and on...";
const stored = truncate(bio, 255);
// Fit a string into a fixed-width terminal column
const label = truncate(filename, 20).padEnd(20);Caps the total output at maxLength characters. If the string is longer, it is cut so the final result including the trailing "..." is at most maxLength chars. The "..." counts toward the limit — `ellipsify(s, 8)` returns at most 5 visible characters plus "...". Throws a RangeError if maxLength is negative.
| Parameter | Type | Description |
|---|---|---|
input | string | The input string. |
maxLength | number | Total character limit of the returned string, including the trailing ellipsis. Must be ≥ 0. |
| returns | string | — |
import { ellipsify } from "koyojs";
ellipsify("A longer sentence here", 12); // "A longer ..."
ellipsify("Short", 10); // "Short" — fits, no ellipsis added
ellipsify("Hello World", 8); // "Hello..."
// "..." is 3 chars, so visible text = length - 3
ellipsify("1234567890", 7); // "1234..."
// Card description preview — limit to 80 characters
const card = { desc: "This product has many remarkable features worth exploring in depth." };
const preview = ellipsify(card.desc, 80);
// Notification message in a toast
const msg = ellipsify(errorMessage, 60);Returns true if the string is a valid e-mail address. Enforces the RFC 5321 practical length limit (320 characters) and requires a non-empty local part, an @ symbol, and a domain with at least a two-character TLD.
| Parameter | Type | Description |
|---|---|---|
input | string | The string to test. |
| returns | boolean | — |
import { isEmail } from "koyojs";
isEmail("user@example.com"); // true
isEmail("user+tag@domain.co.uk"); // true
isEmail("not-an-email"); // false
isEmail("@domain.com"); // false
isEmail("a@b"); // false
isEmail(""); // false
// Form validation before submitting
function handleSubmit(formData: { email: string }) {
if (!isEmail(formData.email)) {
setError("Please enter a valid email address.");
return;
}
submitForm(formData);
}
// Filter out invalid emails from an import list
const validEmails = rawList.filter(isEmail);Returns true if the string is a well-formed HTTP or HTTPS URL. Uses the WHATWG URL parser internally — if the string is not a valid URL the constructor throws and false is returned. Only http: and https: protocols are accepted; all other schemes return false.
| Parameter | Type | Description |
|---|---|---|
input | string | The string to test. |
| returns | boolean | — |
import { isURL } from "koyojs";
isURL("https://example.com"); // true
isURL("http://localhost:3000"); // true
isURL("https://sub.domain.io/path?q=1"); // true
isURL("ftp://files.io/x"); // false — only http/https
isURL("//example.com"); // false — must include protocol
isURL("not a url"); // false
// Validate a user-submitted website link before storing
function saveProfile(data: { website: string }) {
if (data.website && !isURL(data.website)) {
throw new Error("Website must be a valid http/https URL");
}
db.save(data);
}
// Render a clickable link only when the value is a real URL
const href = isURL(user.website) ? user.website : null;Returns true if the string matches a common phone number pattern. Strips formatting characters (spaces, hyphens, dots, parentheses) then checks that the remaining digit string is 7–15 digits, optionally prefixed with +, per ITU-T E.164.
| Parameter | Type | Description |
|---|---|---|
input | string | The string to test. |
| returns | boolean | — |
import { isPhoneNumber } from "koyojs";
isPhoneNumber("+1 (555) 123-4567"); // true
isPhoneNumber("+44 20 7946 0958"); // true
isPhoneNumber("555-123-4567"); // true
isPhoneNumber("5551234567"); // true
isPhoneNumber("123"); // false — too short
isPhoneNumber("abc"); // false
// Contact form validation
function validateContact(form: { phone: string }) {
if (form.phone && !isPhoneNumber(form.phone)) {
return "Enter a valid phone number (e.g. +1 555 123-4567)";
}
}