If you have ever moved code between a JavaScript front end and a Python API, you have felt it: the same idea is userLoginCount in one file and user_login_count in the other. Case styles are not interchangeable decoration — every language, framework and file format has settled on its own naming convention, and matching it is what makes code look native. This guide compares camel case vs snake case vs kebab case, adds PascalCase, CONSTANT_CASE, Title Case and Sentence case, shows where each one is the standard, and covers the edge cases that trip people up.
The seven naming styles at a glance
Every identifier style does the same two jobs: split a phrase into words, then rejoin them with a casing rule and maybe a separator. Here is what each style does to the phrase "user login count":
| Style | Example | Rule |
|---|---|---|
| camelCase | userLoginCount | Words joined directly; first word lowercase, every later word capitalized |
| PascalCase | UserLoginCount | Same joining as camelCase, but the first word is capitalized too |
| snake_case | user_login_count | All lowercase, words joined with underscores |
| kebab-case | user-login-count | All lowercase, words joined with hyphens |
| CONSTANT_CASE | USER_LOGIN_COUNT | All uppercase, words joined with underscores |
| Title Case | User Login Count | Words separated by spaces, each one capitalized |
| Sentence case | User login count | Words separated by spaces, only the first one capitalized |
Two pairs are easy to confuse. camelCase and PascalCase join words identically — the only difference is the very first letter, userLoginCount versus UserLoginCount. snake_case and kebab-case share the same all-lowercase casing and differ only in the separator: underscore versus hyphen. CONSTANT_CASE is simply snake_case shouted, which is why some people call it SCREAMING_SNAKE_CASE.
Where each style is the convention
| Context | Convention | Example |
|---|---|---|
| JavaScript & Java variables, functions, methods | camelCase | getUserById, retryCount |
| Classes in JavaScript, Java, Python, C# | PascalCase | ShoppingCart, HttpClient |
| Python functions & variables (PEP 8) | snake_case | calculate_total |
| Ruby, Rust, PHP, SQL identifiers | snake_case | created_at |
| CSS classes & HTML data attributes | kebab-case | .main-header, data-user-id |
| URLs and slugs | kebab-case | /blog/naming-conventions |
| Constants & environment variables | CONSTANT_CASE | MAX_RETRY_COUNT |
| JSON keys & GraphQL fields | camelCase | firstName |
| Headlines, book titles, headings | Title Case | The Quick Brown Fox |
| UI labels and body copy | Sentence case | Save changes |
These are community standards, not compiler rules. Python's PEP 8 style guide prescribes snake_case for functions and variables, PascalCase (it says CapWords) for classes and UPPER_CASE for constants. Java and JavaScript reach for camelCase everywhere except class names. CSS itself is hyphenated — background-color, font-size — so authors naturally extend kebab-case to class names. And Google's URL guidelines recommend hyphens over underscores in URLs, because a hyphen is treated as a word separator while an underscore glues words into one token for search.
Edge cases: acronyms, numbers and leading digits
Acronyms: XMLHttpRequest or XmlHttpRequest?
Two respectable answers exist. The browser DOM API kept the acronym fully capitalized: XMLHttpRequest. The Google Java style guide instead says treat acronyms as ordinary words, which produces XmlHttpRequest. The .NET design guidelines split the difference: two-letter acronyms stay uppercase (System.IO), but anything longer becomes a normal word — Html, Xml, Json. None of these is wrong; mixing httpRequest and HTTPRequest inside one codebase is. Pick the rule of your language community and apply it everywhere.
Numbers inside identifiers
Digits glue to the word they belong to: sha256Hash, utf8Encode, version2Id. Converters differ on whether a letter–digit boundary counts as a word boundary, so sha-256-hash may normalize to sha256Hash or keep the digits as their own segment — glance at the output whenever numbers are involved rather than assuming.
Leading digits
Identifiers may not start with a digit in JavaScript, Python, Java, C and most other languages — 2faEnabled is a syntax error before it is anything else. Move the digit (enable2fa) or spell the number out (twoFactorAuthEnabled). HTML allows a class attribute to begin with a digit, but the corresponding CSS selector then needs escaping, which is why stylesheets avoid names like .404-page.
Renaming identifiers across languages
Porting code between ecosystems usually means a bulk rename. A reliable procedure:
- Split the source name into words on underscores, hyphens, spaces and camelCase humps, so
getHTTPResponseCodebecomes get / http / response / code. - Decide the acronym rule once for the target style — whether
httprejoins asHttpor staysHTTP— before touching any files. - Rejoin with the target casing and separator:
getHttpResponseCodein Java becomesget_http_response_codein Python. - Search case-sensitively across the whole repo for the old name, including string literals, JSON keys, config files, log messages and database columns that reference it.
The mechanical part is what the Case Converter automates: paste an identifier in any style — it understands spaces, underscores, hyphens and camelCase boundaries — and copy it back as camelCase, snake_case, kebab-case or CONSTANT_CASE. Everything runs in your browser, so even production variable names never leave the page.