camelCase, snake_case, kebab-case and PascalCase: A Naming Guide
What each naming convention means, which languages and platforms expect which style, and how to convert between them without breaking your code.
Naming things is famously one of the hard problems in software, but the *shape* of a name is not the hard part — it is simply convention. Every ecosystem has settled on a preferred style, and following it makes code read as if one person wrote it. This guide explains the four conventions you will meet most often, where each belongs, and the conversion pitfalls that break builds.
The four conventions at a glance
| Style | Example | Where it belongs |
| --- | --- | --- |
| camelCase | userFirstName | JavaScript and TypeScript variables, JSON keys, Java methods |
| PascalCase | UserFirstName | Class and type names in C#, Java, TypeScript; React components |
| snake_case | user_first_name | Python variables, SQL columns, Ruby, C standard library |
| kebab-case | user-first-name | URLs, CSS classes, HTML attributes, npm package names |
Two more appear regularly: SCREAMING_SNAKE_CASE (MAX_RETRY_COUNT) for constants and environment variables, and Train-Case (User-First-Name) for HTTP headers.
camelCase
camelCase starts lowercase and capitalises each subsequent word. It is the default for identifiers in JavaScript, TypeScript, Java and Swift, and it is the convention most JSON APIs follow because the payload is usually consumed by JavaScript.
The rule that trips people up is acronyms. Most style guides — including Google''s and Microsoft''s — recommend treating an acronym as a normal word: parseHtmlResponse, not parseHTMLResponse; userId, not userID. Consistency matters more than the choice itself, but mixed handling in one codebase makes search unreliable.
PascalCase
PascalCase (also called UpperCamelCase) capitalises the first letter too. It signals "this is a type, not a value". In practice that means classes, interfaces, enums, type aliases and React components. React actually enforces it: JSX treats a lowercase tag as an HTML element, so a component named myButton silently renders an unknown tag instead of your component.
snake_case
snake_case joins lowercase words with underscores. Python''s PEP 8 mandates it for variables and functions; SQL uses it for tables and columns because most databases fold unquoted identifiers to lowercase anyway, making userFirstName and userfirstname the same thing. If you have ever wondered why a Postgres query "loses" your camelCase column names, this is why — and the fix is to name columns in snake_case rather than quoting every identifier forever.
kebab-case
kebab-case joins lowercase words with hyphens. Hyphens are illegal in identifiers in most languages, which is exactly why kebab-case is safe in places that are *not* identifiers: URLs, file names, CSS class names, custom HTML elements and package names. Search engines treat a hyphen as a word separator and an underscore as a joining character, so title-case-converter reads as three words to a crawler while title_case_converter reads as one.
Converting between conventions
Conversion is mechanical but easy to get subtly wrong. The safe algorithm is: split the name into words first, then re-join them in the target style.
Splitting is where the bugs live:
- Existing separators — split on
_,-and spaces. - Case boundaries — split between a lowercase and an uppercase letter (
userNamebecomesuser+Name). - Acronym boundaries — split between two uppercase letters followed by a lowercase one, so
HTMLParserbecomesHTML+Parser, notH+TMLParser. - Digits — decide once whether
address2is one word or two, and apply it everywhere.
Once the words are separated, joining is trivial: lowercase and join with _ for snake_case, with - for kebab-case, capitalise all but the first for camelCase, capitalise all for PascalCase.
Our camelCase Converter, snake_case Converter, kebab-case Converter and PascalCase Converter implement exactly this splitting logic, so acronyms and mixed input survive the round trip.
Where conventions collide
Most real applications cross at least one boundary. A React app with a Postgres database usually has snake_case columns, camelCase JavaScript objects, and kebab-case URLs for the same concept. Three sensible ways to handle it:
- Convert at the edge. Map names once, in the data layer, so the rest of the app sees a single convention. Most ORMs and query builders can do this automatically.
- Let the API dictate. If an external API returns snake_case, keep those names untouched in the types that model its response, and convert only when data enters your own domain model.
- Never convert silently in both directions. Round-tripping
HTTPStatusthrough a naive converter can yieldhttpstatus, which no longer converts back. Pick a canonical form and store it.
A short style checklist
- Choose the convention the language community already uses; do not invent a house style.
- Be consistent with acronyms across the entire codebase.
- Use SCREAMING_SNAKE_CASE only for genuine constants and environment variables.
- Keep URLs in kebab-case and lowercase — mixed-case URLs create duplicate-content risk.
- Prefer clear multi-word names over abbreviations; every convention reads better with real words.
Frequently asked questions
Is camelCase or snake_case objectively more readable? Studies are inconclusive and the difference is small. Familiarity dominates: developers read fastest in whatever their ecosystem uses.
Should JSON keys be camelCase or snake_case? Match the consumer. JavaScript clients expect camelCase; Python and Ruby clients often expect snake_case. Document the choice and never mix both in one payload.
Why do URLs use hyphens instead of underscores? Search engines historically treated underscores as word joiners, so case_converter was read as a single token. Hyphens split cleanly into keywords.
What about file names? kebab-case for web assets, snake_case for Python modules, PascalCase for files that export a single class or React component. Case-insensitive file systems on macOS and Windows make inconsistent capitalisation a real source of "works on my machine" bugs.
