The Problem Whitespace Creates in Code
In written human language, spaces separate words naturally. In computing, however, the space character (ASCII 32) is a structural delimiter. Compilers, interpreters, command-line shells, and URL parsers treat whitespace as a separator between distinct commands or arguments, not as part of a single identifier.
To create readable multi-word names for variables, database columns, filenames, and CSS classes without using spaces, software engineering evolved four primary casing conventions. Choosing the wrong convention will violate language idioms, fail style linters, and introduce silent serialization bugs when data travels across boundaries.
Comparison of the Four Major Casing Styles
| Case Style | Example | Delimiter Rule | Primary Ecosystems |
|---|---|---|---|
| camelCase | userFirstName |
First word lowercase, subsequent words capitalized; no symbols | JavaScript, TypeScript, Java, JSON keys, Swift, Go (unexported) |
| snake_case | user_first_name |
All words lowercase, separated by underscores (_) |
Python (PEP 8), Ruby, SQL database tables/columns, Rust, C |
| kebab-case | user-first-name |
All words lowercase, separated by hyphens (-) |
CSS class names, HTML attributes, URL slugs, package names |
| PascalCase | UserFirstName |
Every word capitalized including the first; no symbols | C#, Python classes, React components, TypeScript types & interfaces |
Deep Dive: Where Each Convention Belongs
1. camelCase (Lower Camel Case)
Named after the humps of a camel, camelCase starts with an initial lowercase letter and capitalizes every subsequent word. It is the undisputed standard in JavaScript, TypeScript, Java, and Swift for naming variables, functions, and object methods.
Common Gotcha: Acronyms. Some style guides mandate capitalizing every letter of an acronym (e.g. parseHTTPResponse), while modern guidelines (including Google and TypeScript standards) recommend treating acronyms as regular words (e.g. parseHttpResponse or userId instead of userID).
2. snake_case
snake_case links words together using underscores. In Python, PEP 8 explicitly requires snake_case for functions and variable names. It is also the universal convention for relational databases (SQL), because many SQL engines are case-insensitive by default and fold uppercase letters to lowercase unless quoted.
Variant: SCREAMING_SNAKE_CASE (or CONSTANT_CASE) uses all uppercase letters with underscores (e.g. MAX_RETRY_COUNT) across almost all languages to denote immutable global constants and environment variables.
3. kebab-case (Lisp-case / Slug-case)
kebab-case resembles food threaded onto a skewer, using hyphens to separate lowercase words. Because most programming languages treat the hyphen (-) as a subtraction operator, you cannot use kebab-case for variables in Python, JavaScript, or C (a variable named total-cost is evaluated as total minus cost).
Instead, kebab-case is standard where math operators are not parsed: CSS properties and class selectors (.nav-item-active), HTML custom attributes (data-user-id), and URL paths (/guides/snake-case-vs-camel-case/).
4. PascalCase (Upper Camel Case)
PascalCase capitalizes the first letter of every word. In object-oriented programming, PascalCase distinguishes type definitions from instance variables:
- In JavaScript / TypeScript:
class UserAccount {}(PascalCase) instantiatesconst userAccount = new UserAccount();(camelCase). - In React: JSX elements starting with lowercase (e.g.
<div>) are treated as native HTML tags, while elements starting with PascalCase (e.g.<UserProfile />) are parsed as React components.
The Boundary Problem: JSON Serialization
The single greatest source of friction in modern full-stack development is the boundary between the database, the backend, and the frontend:
- Your PostgreSQL database stores columns in
snake_case(e.g.created_at,billing_address). - Your Python backend queries the database using
snake_casemodels. - Your React frontend expects props and state in
camelCase(e.g.createdAt,billingAddress).
When APIs serialize backend database dictionaries directly to JSON without converting case styles, frontend code ends up with inconsistent property access (props.created_at mixed with props.updatedAt). Modern backend frameworks like Pydantic (Python) or Serde (Rust) provide automatic field alias transforms to convert snake_case to camelCase on output.
Frequently Asked Questions
Why can't I use kebab-case for JavaScript variable names?
JavaScript parses the hyphen (-) as a subtraction operator. If you declare let my-variable = 5;, the JavaScript engine interprets it as attempting to subtract the identifier variable from my, resulting in an immediate SyntaxError: Unexpected token '-'.
Which casing convention is best for REST API JSON responses?
The industry consensus (backed by Google, Microsoft, and the JSON:API standard) recommends camelCase for JSON payload keys. Since JSON is native to JavaScript and TypeScript frontends, camelCase allows developers to consume properties directly without linting warnings.
Why do URLs use kebab-case instead of snake_case?
Search engines treat hyphens as true word separators, recognizing snake-case as two distinct keywords ("snake" and "case"). Underscores, however, were historically indexed as character joiners, causing search bots to index snake_case as a single conjoined token.
What is the difference between camelCase and PascalCase?
The sole difference is the very first letter: camelCase starts with a lowercase letter (e.g. itemCount), whereas PascalCase starts with a capital letter (e.g. ItemCount). In languages like TypeScript and C#, PascalCase is reserved for types and classes, while camelCase is used for variables and properties.