Developer Docs

capstring is a small, serious, zero-dependency library for turning text into any case, code convention, encoding, or ridiculous fun style. Unicode and emoji safe. It ships a CLI, TypeScript types, and a free HTTP API, all documented on this page.

LibraryNode 22+, any modern browser, Deno, BunInstall
CLInpx capstring kebab "hello world"Command line
HTTP APIhttps://capstring.netlify.app/apiHTTP API ยท API Reference
PlaygroundType, click to copyOpen
  • Smart tokenizer: XMLHttpRequest, hello_world, hello-world, and helloWorld all split correctly.
  • Real slug: diacritics folded, punctuation dropped, ASCII only.
  • Unicode and emoji safe: flags, ZWJ sequences, keycaps, and combining accents survive every style.
  • Zero dependencies, 7 files, under 40 kB on npm, and a test fails if that ever grows.
  • 100% test coverage, every behavior change recorded in the changelog.

Install

Requires Node 22.13 or newer. ES modules only: use import, not require. No runtime dependencies are installed.

In a browser with no bundler, import the library file straight from a CDN. It is dependency-free and browser-safe.

Transform a string

capstring(str, style = 'same', options = {}) returns the transformed string. The default export and the named export are the same function.

ParameterTypeDefaultDescription
strstringText to transform
styleStyle'same'A style name, see Styles
options.strictbooleanfalseThrow instead of returning false or the input

Passing a non-string returns false. An empty string returns ''. An unknown style returns the input unchanged. These are deliberate so the function is safe to call with untrusted values.

Strict mode

Turn on strict to throw instead: a TypeError when str is not a string, a RangeError when style is not a known style. The CLI and the HTTP API always validate strictly.

Every style at once

capstringAll(str, options) runs every style and returns an object keyed by style name in canonical order. Same options and same non-string behavior as capstring. The playground is built on this one call.

Discover styles

ExportWhat it is
STYLESFrozen array of every style name in canonical order. New styles are appended, so indexes are stable.
CATEGORIESFrozen object grouping every style exactly once: case, code, fun, encoding, art.
getStyles()A fresh, mutable copy of STYLES.
isValidStyle(value)true for a style name. In TypeScript it narrows value to Style.

Styles

Every style, what it does, and how it handles the edges. Outputs on this page are computed live by the library, so they are exactly what you get. The first example is always hello world.

Command line

The package ships a capstring executable. Two ways to get it:

# no install, runs the latest version each time
npx capstring kebab "hello world"

# or install once and use it anywhere
npm install -g capstring
capstring kebab "hello world"
capstring <style> [text...]     Transform text (reads stdin when no text is given)
capstring --all [text...]       Print every style
capstring --count [text...]     Count words, characters, and spaces
capstring --list                List style names

  -a, --all        Print every style
  -c, --count      Count words, characters, and spaces
  -l, --list       List style names, one per line
      --json       JSON output
  -h, --help       Show this help
  -v, --version    Show version
  --               End of options

Multiple text arguments are joined with one space. Flags may appear anywhere. With no text argument the CLI reads all of stdin and strips one trailing newline, so it slots into pipelines. Multiline stdin is treated as one string; in the --all table, line breaks inside a result are shown escaped so every style stays on one row.

Exit codeMeaning
0Success
2Usage error: unknown style, unknown option, or no text given on a terminal

TypeScript

Types ship in the package. Every style name is a string literal in the Style union, so editors autocomplete them and typos fail to compile. capstring and capstringAll are overloaded so the return type matches the input: a string in gives a string back, unknown in gives string | false. The style parameter accepts Style | (string & {}), which keeps autocomplete while still allowing arbitrary strings.

A test in the repository fails if the union ever drifts from the runtime STYLES array.

HTTP API

The same transformations over HTTP, for any language or no code at all. Base URL https://capstring.netlify.app/api, no key, CORS enabled, cacheable. The interactive API Reference lets you try every endpoint in the browser.

EndpointReturns
GET /api/:style/:text{ input, style, output }
GET /api/all/:textevery style at once
POST /api/batch{ "style": "kebab", "texts": ["a", "b"] }, up to 1,000
GET /api/spell/:textspell-corrected text and corrections, optional ?style=
GET /api/count/:textwords, characters, characters without spaces
GET /api/lorem/:countlorem ipsum, 1 to 1000 words, optional ?style=
GET /api/badge/:style/:textSVG badge, ?label= to override
GET /api/stylesstyle names and categories

Output formats

JSON by default. Choose another with a file extension on the path, a format query parameter, or an Accept header. The extension wins when more than one is given. Errors come back in the same format with a matching status.

FormatExtensionAccept
JSON.jsonapplication/json
Plain text.txttext/plain
HTML.htmltext/html
XML.xmlapplication/xml
YAML.yaml or .ymltext/yaml
CSV.csvtext/csv
JSONP.jsonp with ?callback=application/javascript
SVG image.svgimage/svg+xml
PNG image.pngimage/png

Use ?text= instead of the path when the text contains slashes or ends in an extension. Add ?pretty=1 for indented JSON. Image formats draw a single line and cut output beyond 200 characters with an ellipsis.

Limits and caching

WhatLimit
Text10,000 characters (GET URLs are capped at about 8 KB by the host; use POST /api/batch for longer text)
Spell check500 characters, 50 corrections per request
Batch1,000 texts, 100,000 characters in total
Lorem1,000 words
Badge label100 characters

Deterministic responses carry Cache-Control: public, max-age=86400. Anything involving the random style or a POST body is no-store.

What ships on npm

FilePurpose
index.jsThe whole library, browser-safe
index.d.tsTypeScript declarations
cli.jsCLI logic as a testable main(argv, io)
bin/capstring.jsThe npx capstring executable

Plus package.json, README.md, and LICENSE. Zero dependencies, sideEffects: false so bundlers can tree-shake it. Release notes live in the changelog.