Six cases, one phrase
All six conversions share the same first step. The input is broken into words — on spaces, on punctuation, and on the internal capitals of an existing identifier — and then rejoined with a different separator and capitalisation. That shared splitter is what lets you convert between conventions, and not only out of prose.
| Case | Output | Typical home |
|---|---|---|
| camelCase | getUserIdFromApiResponse | JavaScript, Java and C# members; local variables |
| PascalCase | GetUserIdFromApiResponse | Classes and types nearly everywhere; exported Go names |
| snake_case | get_user_id_from_api_response | Python, Rust and Ruby functions and variables |
| SCREAMING_SNAKE | GET_USER_ID_FROM_API_RESPONSE | Constants and environment variables |
| kebab-case | get-user-id-from-api-response | CSS classes and custom properties, URL slugs, CLI flags |
| dot.case | get.user.id.from.api.response | Config keys, property files, logger names, i18n keys |
Note what happened to ID and API: both folded to Id and
Api. That is deliberate and it follows the Google Java Style Guide, which spells the
procedure out — divide the phrase into words, then “lowercase everything (including acronyms), then
uppercase only the first character” of each word. The guide spells its own examples
XmlHttpRequest and newCustomerId; the forms it turns away from are
XMLHTTPRequest and newCustomerID. Keeping acronyms in full caps produces runs like
parseHTTPURLResponse where the eye cannot find the word boundaries.
Every spelling normalises to the same identifier
The splitter treats an existing identifier and a plain English phrase identically, which means converting between conventions needs no special mode. Here are five spellings of one name, each run through the tool:
| Input | Words detected | camelCase | snake_case |
|---|---|---|---|
| get user name | get · user · name | getUserName | get_user_name |
| getUserName | get · user · name | getUserName | get_user_name |
| get_user_name | get · user · name | getUserName | get_user_name |
| GET-USER-NAME | get · user · name | getUserName | get_user_name |
| Get User Name | get · user · name | getUserName | get_user_name |
That is the everyday use: rename a database column to a JavaScript property, turn a class name into a URL slug, or convert a spreadsheet of headings into constants. Paste the whole column and every line is converted independently.
How the splitter handles the awkward cases
| Input | Words detected | camelCase | Why |
|---|---|---|---|
| parse HTTP response body | parse · http · response · body | parseHttpResponseBody | A standalone acronym folds to one word. |
| XMLHttpRequest | xml · http · request | xmlHttpRequest | A capital run followed by a capitalised word splits at the seam. |
| get user ID from API response | get · user · id · from · api · response | getUserIdFromApiResponse | Two acronyms, both folded — matching Google Java Style. |
| utf8 encoder | utf8 · encoder | utf8Encoder | Digits stay attached to the word they follow. |
| user ID 42 | user · id · 42 | userId42 | A standalone number becomes its own word. |
| user's name | users · name | usersName | An apostrophe stays inside the word and is dropped from the identifier — not treated as a word boundary. |
| IPv6 address | i · pv6 · address | iPv6Address | Known limit: a real word with an internal capital splits. Type ipv6 instead. |
The last row is a real limitation, printed here in full. IPv6 is one
word that happens to contain an internal capital, and nothing distinguishes that from the genuine
word boundary in getUser without a dictionary. The same applies to
iOS and eBay. Type them in lowercase — ipv6 — and they come
through as a single word.
Which convention belongs where
Identifier casing is not a matter of taste in most ecosystems; it is written down, and linters enforce it. Every row below names the document behind it, and the last column says how far that document goes: spec where a first-party specification, style guide or documentation page states the rule, convention where the practice is near-universal but no first-party document actually mandates it. 3 of the 17 rows carry the weaker label, and the column shows which ones.
| Where | What | Convention | Stated in | Basis |
|---|---|---|---|---|
| Python | functions, variables, modules | snake_case | PEP 8, “Naming Conventions” | spec |
| Python | classes | PascalCase (PEP 8 calls it CapWords) | PEP 8, “Naming Conventions” | spec |
| Python | module-level constants | SCREAMING_SNAKE | PEP 8, “Constants” | spec |
| Java | methods and non-constant fields | camelCase | Google Java Style Guide §5.2 | spec |
| Java | classes | PascalCase | Google Java Style Guide §5.2 | spec |
| Java | constants | SCREAMING_SNAKE | Google Java Style Guide §5.2 | spec |
| Go | everything — exported vs unexported is the initial capital | PascalCase / camelCase, never underscores | Effective Go, “MixedCaps” | spec |
| Rust | functions, variables, modules | snake_case | Rust API Guidelines / RFC 430 | spec |
| Rust | types, traits, enum variants | PascalCase (UpperCamelCase) | Rust API Guidelines / RFC 430 | spec |
| C# | methods, properties, types | PascalCase | .NET naming guidelines, Microsoft Learn | spec |
| C# | parameters and local variables | camelCase | .NET naming guidelines, Microsoft Learn | spec |
| CSS | custom properties and class names | kebab-case | No spec: CSS mandates only the leading “--” on a custom property (<dashed-ident>) and is case-sensitive; kebab-case is near-universal practice | convention |
| HTML | data-* attributes | kebab-case (exposed to JS as camelCase via dataset) | HTML Living Standard, “dataset” | spec |
| URLs | path slugs | kebab-case | Google Search Central: use hyphens, not underscores, in URLs | spec |
| Shell / CI | environment variables | SCREAMING_SNAKE | POSIX reserves all-uppercase names for the standard’s own variables and suggests lowercase for application-private ones; SCREAMING_SNAKE for project config is practice | convention |
| Kubernetes | object names | kebab-case (RFC 1123 label: lowercase, digits, hyphen) | Kubernetes docs, “Object Names and IDs” | spec |
| Java properties / logging | config keys and logger names | dot.case | java.util.logging documents dot-separated hierarchical logger names; java.util.Properties documents no key convention, so config keys are practice | convention |
Two rows deserve a second look. Go is unusual in having no separate convention for
public and private names: the initial capital is the visibility marker, so
UserName is exported and userName is not, and underscores are ruled out
entirely. URLs are kebab-case for a documented reason and not a stylistic one:
Google's guidance is to use hyphens rather than underscores in URLs, because a hyphen reads as a
word separator and an underscore does not.
Practical notes
One identifier per line. The converter treats each line separately, so a paragraph of prose becomes one very long identifier — which is almost never what you want. Split your input into lines first and it does the right thing for every one of them.
Accents and non-Latin letters are kept. The splitter works on Unicode letters, not
ASCII, so día laboral becomes díaLaboral. Most languages accept that in an
identifier; if your target does not, strip the accents before converting.
Undo is per conversion. Try camelCase, decide you wanted kebab-case, and just press the other button — the splitter re-derives the same words either way. Undo is there for when you want the original phrase back, punctuation and all.