Browse packages

Package · v0.22.1

string

Standard library strings

String utilities for JavaScript runtimes.

What is @rcompat/string?#

A cross-runtime module providing common string operations: Base64 encoding, case conversion, dedentation, glob pattern matching, and UTF-8 byte length calculation. Works consistently across Node, Deno, and Bun.

Installation#

bash
npm install @rcompat/string
bash
pnpm add @rcompat/string
bash
yarn add @rcompat/string
bash
bun add @rcompat/string

Usage#

Base64 encoding/decoding#

js
import string from "@rcompat/string";

// encode to Base64
const encoded = string.Base64.encode("Hello, World!");
console.log(encoded); // "SGVsbG8sIFdvcmxkIQ=="

// decode from Base64
const decoded = string.Base64.decode(encoded);
console.log(decoded); // "Hello, World!"

Convert to camelcase#

js
import string from "@rcompat/string";

// from kebab case
string.toCamelCase("hello-world"); // "helloWorld"
string.toCamelCase("my-component"); // "myComponent"

// from snake case
string.toCamelCase("hello_world"); // "helloWorld"
string.toCamelCase("user_profile"); // "userProfile"

// mixed
string.toCamelCase("my-user_name"); // "myUserName"

Dedent multi-line strings#

js
import string from "@rcompat/string";

// as a template tag
const sql = string.dedent`
  SELECT *
  FROM users
  WHERE active = true
`;
// "SELECT *\nFROM users\nWHERE active = true"

// with interpolation
const table = "users";
const query = string.dedent`
  SELECT *
  FROM ${table}
  WHERE id = 1
`;

Convert glob to RegExp#

js
import string from "@rcompat/string";

// simple wildcards
const pattern = string.glob("*.js");
pattern.test("app.js"); // true
pattern.test("app.ts"); // false
pattern.test("dir/app.js"); // false

// double wildcard (recursive)
const recursive = string.glob("**/*.js");
recursive.test("app.js"); // true
recursive.test("src/app.js"); // true
recursive.test("src/lib/app.js"); // true

// single character wildcard
const single = string.glob("file?.txt");
single.test("file1.txt"); // true
single.test("fileA.txt"); // true
single.test("file10.txt"); // false

Convert to slug#

js
import string from "@rcompat/string";

string.toSlug("Hello World");  // "hello-world"
string.toSlug("café");         // "cafe"
string.toSlug("naïve");        // "naive"
string.toSlug("foo  bar");     // "foo-bar"

Capitalize first letter#

js
import string from "@rcompat/string";

string.upperfirst("hello"); // "Hello"
string.upperfirst("world"); // "World"
string.upperfirst("javaScript"); // "JavaScript"

Get UTF-8 byte length#

js
import string from "@rcompat/string";

// ASCII (1 byte per character)
string.utf8.bytelength("hello"); // 5

// unicode (variable bytes)
string.utf8.bytelength("héllo"); // 6 (é = 2 bytes)
string.utf8.bytelength("日本語"); // 9 (3 bytes each)
string.utf8.bytelength("🎉"); // 4 (emoji = 4 bytes)

Get UTF-8 size#

js
import string from "@rcompat/string";

string.utf8.size("hello"); // 5
string.utf8.size("héllo"); // 6
string.utf8.size("日本語"); // 9
string.utf8.size("🎉"); // 4

API Reference#

Base64#

ts
import string from "@rcompat/string";

string.Base64.encode(decoded: string): string;
string.Base64.decode(encoded: string): string;

Object with methods for Base64 encoding and decoding.

Method Description
encode Encode a string to Base64
decode Decode a Base64 string

toCamelCase#

ts
import string from "@rcompat/string";

string.toCamelCase(string: string): string;

Converts kebab case (a-b) or snake case (a_b) strings to camel case (aB).

dedent#

ts
import string from "@rcompat/string";

string.dedent(string: string): string;
string.dedent(strings: TemplateStringsArray, ...values: unknown[]): string;

Removes common leading whitespace from multi-line strings. Can be used as a template tag or called directly with a string.

glob#

ts
import string from "@rcompat/string";

string.glob(pattern: string): RegExp;

Converts a glob pattern to a RegExp.

Pattern Matches
* Any characters except /
** Any characters including /
? Any single character
. Literal dot (auto-escaped)
[a-z] A character class or range

**/ matches zero or more path segments, so **/*.js matches both app.js and src/app.js. Other regular-expression syntax is treated literally.

toSlug#

ts
import string from "@rcompat/string";

string.toSlug(string: string): string;

Converts a string to a URL-safe slug. Lowercases, reduces accented Latin characters to their ASCII base (e.g. é → e), and replaces runs of non-alphanumeric characters with -. Non-Latin characters (e.g. CJK) are stripped. Returns "" for fully non-Latin input.

upperfirst#

ts
import string from "@rcompat/string";

string.upperfirst(string: string): string;

Capitalizes the first character of a string.

utf8.bytelength#

ts
import string from "@rcompat/string";

string.utf8.bytelength(string: string): number;

Returns the UTF-8 byte length of a string using TextEncoder.

utf8.size#

ts
import string from "@rcompat/string";

string.utf8.size(string: string): number;

Calculates UTF-8 byte size directly from Unicode code points without allocating an encoded byte array.

Examples#

Generate component names#

js
import string from "@rcompat/string";

function toComponentName(filename) {
  // "my-button.svelte" -> "MyButton"
  const name = filename.replace(/\.\w+$/, "");
  return string.upperfirst(string.toCamelCase(name));
}

toComponentName("my-button.svelte"); // "MyButton"
toComponentName("user_profile.vue"); // "UserProfile"

Build SQL queries#

js
import string from "@rcompat/string";

function buildQuery(table, conditions) {
  return string.dedent`
    SELECT *
    FROM ${table}
    WHERE ${conditions.join(" AND ")}
    ORDER BY created_at DESC
  `;
}

const query = buildQuery("users", ["active = true", "role = 'admin'"]);

File matching#

js
import string from "@rcompat/string";

function matchFiles(files, pattern) {
  const regex = string.glob(pattern);
  return files.filter((file) => regex.test(file));
}

const files = ["app.js", "app.ts", "src/utils.js", "src/lib/helper.js"];

matchFiles(files, "*.js"); // ["app.js"]
matchFiles(files, "**/*.js"); // ["app.js", "src/utils.js", "src/lib/helper.js"]
matchFiles(files, "src/**/*.js"); // ["src/utils.js", "src/lib/helper.js"]

Validate content length#

js
import string from "@rcompat/string";

function validateContent(content, maxBytes = 1024) {
  const bytes = string.utf8.bytelength(content);
  if (bytes > maxBytes) {
    throw new Error(`Content exceeds ${maxBytes} bytes (got ${bytes})`);
  }
  return content;
}

validateContent("Hello"); // OK
validateContent("日本語".repeat(500)); // Error: exceeds limit

Encode data for URL#

js
import string from "@rcompat/string";

function encodeState(state) {
  const json = JSON.stringify(state);
  return string.Base64.encode(json);
}

function decodeState(encoded) {
  const json = string.Base64.decode(encoded);
  return JSON.parse(json);
}

const state = { page: 1, filter: "active" };
const encoded = encodeState(state); // "eyJwYWdlIjoxLCJmaWx0ZXIiOiJhY3RpdmUifQ=="
const decoded = decodeState(encoded); // { page: 1, filter: "active" }

Cross-Runtime Compatibility#

Runtime Supported
Node.js ✓
Deno ✓
Bun ✓

No configuration required — just import and use.

License#

MIT

Contributing#

See CONTRIBUTING.md in the repository root.