camelCase vs snake_case vs kebab-case: when to use each
August 4, 2026 · 8 min read
There's no technical reason a JSON key can't be kebab-case or a CSS class can't be camelCase - parsers don't care. The conventions exist entirely for human readability and ecosystem consistency, which is exactly why they conflict the moment data crosses a language boundary: a REST API written in Python naturally wants snake_case fields, but the JavaScript frontend consuming it wants camelCase variables, and the URL routing it all sits behind wants kebab-case paths.
Why every ecosystem picked a different case
JavaScript and Java both inherited camelCase from C-family conventions where identifiers needed to stay short and case was cheap to type-check visually. Python's style guide (PEP 8) explicitly prefers snake_case for readability, a convention shared with Rust and Ruby. Kebab-case won out for URLs and CSS class names specifically because underscores in early web fonts and some legacy systems were visually easy to lose - hyphens read better in lowercase, all-punctuation contexts.
None of this is a technical constraint your code cares about at runtime. It's entirely about matching the reader's expectations for the file they're looking at.
The naming convention cheat sheet
camelCase - JavaScript/TypeScript variables and functions, Java methods, JSON keys in JS-authored APIs. PascalCase - class names and React/Vue component names in almost every language. snake_case - Python variables and functions, Rust variables, SQL column names, most REST APIs authored in Python or Ruby. kebab-case - URL paths, CSS classes, HTML data attributes, command-line flags. CONSTANT_CASE - constants and environment variable names across almost every language.
Where identifiers actually break
The hard part of converting between these isn't applying the target format - it's correctly figuring out where one word ends and the next begins in the source. user_first_name is easy: split on underscores. userFirstName needs to split at every lowercase-to-uppercase transition. UserID is the genuinely ambiguous case: is that "User" + "ID", or "User" + "I" + "D"? Most tooling (and most style guides) treat a run of consecutive capitals as a single word, so UserID splits to "user" and "id" - which matches how people actually read it out loud.
Converting between them safely
Once word boundaries are correctly identified, generating any target case is mechanical: lowercase everything and join with underscores for snake_case, join with hyphens for kebab-case, capitalize each word and concatenate for PascalCase, same but lowercase the first word for camelCase. The risk in hand-converting is almost always in the boundary-detection step, not the reassembly - which is exactly the part worth automating rather than doing with a find-and-replace across underscores and hyphens.
FAQ
- Which case should JSON API keys use?
- There's no universal standard - match whatever the API's primary implementation language conventionally uses, and stay consistent across the whole API rather than mixing conventions field by field.
- Is kebab-case valid in JavaScript variable names?
- No - a hyphen is parsed as a minus sign, so JavaScript identifiers can't contain hyphens at all. kebab-case is safe for URLs, CSS, and string values, but never for variable or property names.
- How are acronyms like "URL" or "ID" handled when converting?
- Consecutive capital letters are treated as one word boundary, so "parseURLPath" splits into "parse", "url", "path" - matching how most style guides expect acronyms to be treated.