Skip to content

Text Case Converter

Convert text between common casing styles.

Text case conversion changes the boundary-and-capitalization style of a string without changing its words. The tool above converts between the common cases in your browser; nothing leaves your machine.

The cases

CaseExampleWhere it’s used
camelCaseuserIdTokenJavaScript variables, Java methods
PascalCaseUserIdTokenClass names in most languages, React components
snake_caseuser_id_tokenPython, Ruby, Rust (vars), database column names
SCREAMING_SNAKE_CASEUSER_ID_TOKENConstants, environment variables
kebab-caseuser-id-tokenURLs, CSS classes, filenames in many ecosystems
Title CaseUser Id TokenHeadlines, button labels
Sentence caseUser id tokenBody text, error messages
lowercaseuser id tokenStripped of all case info
UPPERCASEUSER ID TOKENEmphasis, legacy systems

Conversion between any two is mechanical: split the input into words, then re-join with the target separator and capitalization rule.

Word-boundary detection is the hard part

Splitting into words is where most converters disagree. The boundary rules:

  1. Existing separator. A -, _, or space already marks a boundary.
  2. Lowercase-to-uppercase transition. userId → user, Id. The transition point is a boundary.
  3. Uppercase-to-uppercase-followed-by-lowercase. IDToken → ID, Token. The capital that begins a new word is detected by the lowercase that follows it.
  4. Letter-to-digit transition. Some converters split version2 → version, 2; others keep them joined. Conventions vary.

Worked example. Splitting XMLHttpRequest:

X M L H t t p R e q u e s t
↑       ↑       ↑                ← boundary candidates

The transitions: L → H is uppercase-to-uppercase, but H is followed by t (lowercase), so H starts a new word. Words: XML, Http, Request. The result in snake_case: xml_http_request. (Note that Http becomes http, not h_t_t_p — once the word boundaries are set, lettering inside a word is not further split.)

Acronym handling

The case conversion that breaks people most often is acronyms in camelCase. Two conventions exist:

  • Strict camelCase: every acronym becomes camel-cased. URL → Url, so parseURL → parseUrl.
  • Acronym-preserving: acronyms stay all-caps. parseURL stays parseURL.

JavaScript libraries lean toward strict (JSON.parse, XMLHttpRequest is the historical exception). Java leans toward acronym-preserving in newer code (getURL in JDK; getUrl in modern frameworks). The tool above defaults to strict camelCase because the round-trip behavior is more predictable: camelToSnake('parseURL') → parse_u_r_l is bad; parseUrl → parse_url is the round-trip-safe form.

If you need acronym-preserving conversion for legacy code, post-process the output by hand for the affected acronyms.

Where case conversion goes wrong

  • Existing internal capitalization that isn’t a word boundary. A product name like iPhone has a capital P that isn’t intended as a word boundary. Naïve split-on-uppercase-transitions produces i, Phone. Most converters accept this as a known limitation.
  • Numbers in identifiers. Is mp3Player two words (mp3, player) or three (mp, 3, player)? Different style guides answer differently.
  • Locale-specific case rules. İ (capital I with dot) lowercases to i in Turkish but i (no dot) in English. ASCII-only converters get this right by default; Unicode-aware converters need explicit locale.
  • Round-trip safety. Most case conversions don’t round-trip. userID → user_i_d (snake_case) → userId (camelCase) → user_id (snake_case). The original capitalization is gone after the first conversion.

When to use which case

The choice is usually dictated by the receiving system, not by personal preference:

  • JSON API field names. snake_case is the common convention in REST APIs (Python and Ruby influence). camelCase appears in JavaScript-first APIs.
  • GraphQL. camelCase by spec convention.
  • Database column names. snake_case in most SQL databases (case-folding behavior of bare identifiers in PostgreSQL is the practical reason).
  • URL paths. kebab-case for SEO and readability (/blog-posts/my-first-post).
  • CSS class names. kebab-case for BEM and Tailwind; camelCase for CSS-in-JS.
  • Environment variables. SCREAMING_SNAKE_CASE always (DATABASE_URL, API_KEY).
  • File names. kebab-case for the web; depends on framework otherwise (UserService.java is PascalCase by convention, while Python prefers user_service.py).

Common pitfalls

  • Converting and then comparing. If two systems disagree on acronym handling, userID === userId is false. Pick a canonical case at the boundary and stick to it.
  • Reversing without context. Converting snake_case to camelCase is unambiguous. Converting camelCase to snake_case is ambiguous when the original had ALL_CAPS segments.
  • Locale forgetfulness. ASCII converters silently mishandle Turkish, German ß, and Greek case rules. For non-ASCII input, use a locale-aware Unicode case-conversion library, not a regex.

For other text utilities, see slugify (which is essentially “convert anything to URL-safe kebab-case”) and the text reverser.