camelCase vs snake_case vs kebab-case Explained
camelCase, snake_case, and kebab-case are three conventions for writing multi-word names: camelCase capitalizes every word after the first, snake_case joins words with underscores, and kebab-case joins them with hyphens. In practice: use camelCase for JavaScript, Java, and JSON keys; snake_case for Python, SQL, and Ruby; kebab-case for URLs, CSS, and file names.
What Each Naming Convention Looks Like
The same concept written five ways, and where each form is at home:
| Convention | Example | Typical use | |---|---|---| | camelCase | userProfileUrl | JavaScript and TypeScript variables and functions, Java methods, JSON keys | | snake_case | user_profile_url | Python and Ruby variables and functions, SQL column names, Rust, PHP | | kebab-case | user-profile-url | URLs and slugs, CSS class names, HTML attributes, file names, npm packages | | PascalCase | UserProfileUrl | Class names, React components, C# and .NET methods | | CONSTANT_CASE | MAX_RETRY_COUNT | Constants, environment variables, configuration flags |
The first three cause the most confusion because they encode the same information differently. Note that camelCase and PascalCase differ only in the first letter; the distinction matters in languages like Java and C#, where class names start uppercase and everything else starts lowercase.
Why Each Convention Exists
Each convention is not arbitrary — it is written into the official style guides of the ecosystems that use it.
snake_case is mandated by Python's PEP 8, which specifies lowercase words separated by underscores for function and variable names. SQL culture settled on the same style because identifiers are traditionally case-insensitive there, and uppercase letters would silently vanish in some databases. Ruby and Rust adopted it from similar reasoning, which is why nearly every database you will ever query has snake_case columns.
camelCase comes from Java's official style guide ("lowerCamelCase" for methods and variables) and was carried into JavaScript, where it is now near-universal. It avoids the shift key for the most part and reads compactly in code that calls many functions in sequence.
kebab-case dominates anywhere hyphens are legal and underscores are risky:
- URLs. Google's own documentation recommends hyphens over underscores in URLs, because Google treats a hyphen as a word separator but treats an underscore as a word joiner. To Google's indexer,
user-profile-urlis three tokens;user_profile_urlis one opaque token. - DNS and domains. Underscores are not allowed in hostnames, so lowercase hyphenated names became the habit everywhere a URL might be split across lines or spoken aloud.
- CSS and HTML. CSS properties (
background-color) and HTML attributes (data-user-id) use hyphens, so class names follow suit.
One hard rule to remember: hyphens are illegal in variable names in virtually every programming language, because the parser reads user-profile as user minus profile. That is the single biggest source of naming-convention errors when moving between web work and code.
Step-by-Step: Convert Between Conventions
Whether you are renaming a Python function to use in JavaScript or turning a database column into a URL slug, the conversion is a three-step mechanical process.
- Split the name into words. Detect word boundaries: underscores and hyphens split directly; for camelCase or PascalCase, split before every uppercase letter.
userProfileUrlbecomesuser,Profile,Url. - Lowercase everything.
user,profile,url. - Rejoin according to the target convention. camelCase: capitalize every word except the first →
userProfileUrl. snake_case: join with underscores →user_profile_url. kebab-case: join with hyphens →user-profile-url. PascalCase: capitalize every word including the first →UserProfileUrl.
Worked example, converting user_profile_url to all three targets:
| Target | Result |
|---|---|
| camelCase | userProfileUrl |
| PascalCase | UserProfileUrl |
| kebab-case | user-profile-url |
Two edge cases trip people up:
- Consecutive capitals (acronyms).
parseHTTPResponseshould convert toparse_http_response, notparse_h_t_t_p_response. Treat a run of uppercase letters followed by a lowercase letter as one word:HTTPResponsesplits asHTTP,Response. - Leading uppercase.
Userin PascalCase becomes simplyuserin camelCase — the first word never gets capitalized in camelCase, even when converting from PascalCase.
If you are renaming across a whole codebase, do the conversion mechanically first, then fix acronym handling by search: look for single-letter underscore sequences like _h_ that indicate a botched acronym split.
Is kebab-case ever valid in JavaScript variables?
No. In JavaScript (as in Python, Java, C, and most languages), a hyphen is the subtraction operator, so let user-name = "x" is a syntax error. Kebab-case is only for contexts that treat names as opaque strings: URLs, CSS classes, HTML attributes, file names, and package names. If you find yourself wanting hyphens in code, the convention you want is camelCase.
Which case should JSON API keys use?
There is no standard, so the rule is: match the ecosystem your consumers live in. APIs designed for JavaScript front ends almost always use camelCase keys; APIs built on Python or Ruby back ends often expose snake_case. Whichever you choose, be consistent across every endpoint, and convert at the serializer boundary if your server language and API casing differ — most frameworks (FastAPI, Rails, Jackson) have a single setting for this.
Do underscores or hyphens affect SEO?
For URLs, yes. Google has stated for years that it recommends hyphens: its crawler segments my-page into the words "my" and "page", but reads my_page as the single word "my_page". That means an underscored URL is a worse match for searches containing the individual words. This does not apply to code identifiers — search engines never see your variable names — only to anything that ends up in a public URL.
Stop Converting by Hand
Converting names is quick, but doing it by hand across a schema, an API response, and a set of route paths invites typos — especially with acronym edge cases. Paste any name into the free Utilvy Case Converter and it converts instantly between camelCase, snake_case, kebab-case, PascalCase, and CONSTANT_CASE. Working with API payloads afterward? The JSON Formatter highlights key names and syntax errors in one click.