Case Converter ยท 6 min read
camelCase vs snake_case vs kebab-case: Which Should You Use?
Naming conventions are not arbitrary preferences โ they have technical origins, ecosystem histories, and readability implications. Here is the full breakdown.
The Three Major Conventions
Three naming conventions dominate programming and web development:
- camelCase โ words joined with no separator, each new word capitalised:
getUserById,maxRetryCount - snake_case โ words joined with underscores, all lowercase:
get_user_by_id,max_retry_count - kebab-case โ words joined with hyphens, all lowercase:
get-user-by-id,max-retry-count
There are variants within these: PascalCase (UpperCamelCase) capitalises the first word too (GetUserById), and SCREAMING_SNAKE_CASE uses all caps with underscores (MAX_RETRY_COUNT). Each convention occupies a specific niche.
camelCase: The JavaScript Default
camelCase is the standard in JavaScript, TypeScript, Java, Swift, and most C-family languages. It emerged from these languages' design traditions and was popularised at scale by Java in the 1990s โ Java's class libraries used camelCase consistently for methods and variables.
In web development, camelCase is used for:
- JavaScript variable and function names (
const myVariable,function handleClick()) - JSON object keys when following JavaScript conventions (
{ "userId": 123 }) - CSS-in-JS property names (
backgroundColor,fontSize) - React component props (
onClick,className)
PascalCase (the capitalised variant) is reserved in most JavaScript ecosystems for class names, React components (MyComponent), and TypeScript interface names (UserProfile). This distinction โ camelCase for values, PascalCase for types โ is enforced by linters like ESLint and style guides from Google, Airbnb, and others.
snake_case: The Python Default
snake_case is the standard in Python, Ruby, PHP (for functions), Rust, and most database contexts. Python's official style guide (PEP 8, published in 2001 by Guido van Rossum and Barry Warsaw) explicitly specifies snake_case for all variable names, function names, and module names.
In database work, snake_case is nearly universal. SQL column names like user_id, created_at, and first_name follow snake_case because SQL is case-insensitive and most databases normalise identifiers to lowercase. Underscores are unambiguous word separators that survive this normalisation; camelCase does not.
SCREAMING_SNAKE_CASE is used for constants across many languages โ Python, C, C++, Rust, and others. The convention signals "this value does not change" at a glance: MAX_CONNECTIONS = 100, DEFAULT_TIMEOUT = 30.
kebab-case: The Web URL Standard
kebab-case uses hyphens as separators and is the standard for:
- HTML attributes and custom data attributes (
data-user-id,aria-label) - CSS class names and custom properties (
.nav-link,--primary-color) - URL slugs and file names on the web (
/blog/my-article-title/) - HTML and CSS file names (
reset-styles.css,user-profile.html) - npm package names (
react-router-dom,lodash-es)
kebab-case cannot be used as a variable name in most programming languages because the hyphen is parsed as a minus operator. You cannot write my-variable = 5 in JavaScript or Python. This limits it to contexts where the name is a string or token rather than a code identifier: URLs, HTML, CSS, and configuration files.
Google's SEO documentation explicitly recommends kebab-case for URLs over snake_case. Google treats hyphens as word separators in URLs and indexes them correctly, whereas underscores in URLs have historically been treated as part of the word (though Google claims to handle both now).
Readability Research
A 2009 study by Binkley et al. tested whether camelCase or snake_case identifiers were recognised faster in code. In the original study, snake_case showed a 20% faster recognition rate among subjects not trained in a specific style. A follow-up eye-tracking study by Sharif and Maletic in 2010 found that developers trained in camelCase recognised it as quickly as snake_case, suggesting familiarity matters more than the convention itself.
The practical implication: in a codebase that mixes conventions, the inconsistency imposes a cognitive cost โ not the choice of convention itself.
Which to Use When
| Context | Convention |
|---|---|
| JavaScript/TypeScript variables, functions | camelCase |
| JavaScript/TypeScript classes, React components | PascalCase |
| Python variables, functions, modules | snake_case |
| Python classes | PascalCase |
| Constants (most languages) | SCREAMING_SNAKE_CASE |
| SQL columns, table names | snake_case |
| CSS classes, custom properties | kebab-case |
| HTML attributes | kebab-case |
| URL slugs | kebab-case |
| npm package names | kebab-case |
| JSON keys (JavaScript APIs) | camelCase |
| JSON keys (database-facing) | snake_case |
When Conventions Collide
Full-stack development often requires translation between conventions. A Python backend returning database results in snake_case (user_id) to a JavaScript frontend expecting camelCase (userId) is one of the most common points of friction in web development.
The standard solutions: a serialisation layer that converts snake_case to camelCase on the way out (libraries like humps in JavaScript or Django REST Framework's serializer options), or a consistent API convention enforced across both sides.
GraphQL APIs typically use camelCase field names regardless of backend language, normalising this boundary. REST APIs vary more widely. If you control both sides, pick one and enforce it with a linter.
References
- Binkley, D., et al. (2009). To camelcase or under_score. Proceedings of the 17th IEEE International Conference on Program Comprehension.
- Sharif, B., & Maletic, J.I. (2010). An eye tracking study on camelCase and under_score identifier styles. Proceedings of ICPC 2010.
- PEP 8 โ Style Guide for Python Code. (2001, updated 2023). Python Software Foundation.
- Crockford, D. (2008). JavaScript: The Good Parts. O'Reilly Media.
- Google. (2023). Google JavaScript Style Guide. google.github.io.