Every codebase is full of names — variables, functions, classes, database columns, API
fields, CSS classes. The way you write those names is a naming convention,
and it turns out that the choice between camelCase and snake_case (or
any of the other popular styles) has real downstream consequences on readability, tooling, code
review friction, and even runtime behavior at serialization boundaries.
This article gives you a clear mental model for each style, maps them to the languages and contexts where they belong, and explains what goes wrong when you mix them without a plan.
The Main Case Styles
There are five naming conventions you will encounter in nearly every professional codebase:
- camelCase — the first word is lowercase, every subsequent word starts
with a capital letter. No separators. Example:
getUserProfile,maxRetryCount. - PascalCase (also called UpperCamelCase) — like camelCase but the very
first letter is also capitalised. Example:
UserProfile,HttpClient. - snake_case — all lowercase, words separated by underscores. Example:
get_user_profile,max_retry_count. - kebab-case — all lowercase, words separated by hyphens. Example:
get-user-profile,max-retry-count. Cannot be used as an identifier in most programming languages because-is the subtraction operator. - SCREAMING_SNAKE_CASE — all uppercase with underscores. Reserved for
constants and environment variables. Example:
MAX_RETRY_COUNT,DATABASE_URL.
None of these is inherently superior. What matters is that the choice aligns with the conventions of the language and ecosystem you are working in.
What Each Language Uses
Language communities have developed strong, well-documented conventions over decades. Using the wrong style in a given language makes your code feel foreign to other contributors — even when it compiles and runs correctly.
| Language / Context | Variables & Functions | Classes & Types | Constants |
|---|---|---|---|
| JavaScript / TypeScript | camelCase | PascalCase | SCREAMING_SNAKE_CASE |
| React / Svelte components | camelCase (props) | PascalCase (component name) | SCREAMING_SNAKE_CASE |
| Python | snake_case | PascalCase | SCREAMING_SNAKE_CASE |
| Ruby | snake_case | PascalCase | SCREAMING_SNAKE_CASE |
| Go | camelCase (unexported) | PascalCase (exported) | PascalCase or camelCase |
| Rust | snake_case | PascalCase | SCREAMING_SNAKE_CASE |
| CSS / HTML attributes | kebab-case | N/A | N/A |
| SQL columns | snake_case | N/A | UPPER_SNAKE (keywords) |
| C# variables / fields | camelCase | PascalCase (classes, methods) | PascalCase |
| Java | camelCase | PascalCase | SCREAMING_SNAKE_CASE |
Go is worth a special mention: its convention doubles as an access modifier. Any identifier that starts with an uppercase letter is exported (public); any identifier starting with a lowercase letter is unexported (package-private). The compiler enforces this, so naming convention and visibility are inseparable in Go.
Why Mixing Cases Causes Real Problems
Inconsistent naming is not just an aesthetic complaint. It creates concrete, measurable problems in day-to-day development:
- Linters fail. ESLint's
@typescript-eslint/naming-conventionrule, Rust's built-in compiler warnings, and Python's Flake8 all flag identifiers that violate the expected style. A codebase with mixed conventions will produce a constant stream of lint noise, training developers to ignore warnings — including real ones. - Auto-import and IDE refactoring break down. When the same concept is
spelled differently across files (
userIdvsuser_idvsUserID), IDE "Find All References" and rename refactors miss some occurrences. This leads to runtime bugs that are hard to trace. - Code review friction. Reviewers spend cognitive energy on naming inconsistencies rather than logic and architecture. PR threads fill up with style comments that could have been caught by a formatter.
- Onboarding cost. New team members have to infer the unwritten rules from the existing codebase, often getting them wrong and introducing more inconsistency.
- API serialization mismatches. This is arguably the most dangerous category and deserves its own section.
The Serialization Boundary Problem
The most common case-style collision in web development happens at the boundary between a
backend and a frontend — or between a database and an API. Backends written in Python, Ruby,
or with a PostgreSQL database use snake_case. JavaScript frontends expect camelCase. Without an explicit transform layer, one of two bad things happens:
the frontend uses snake_case identifiers everywhere (polluting the JS codebase), or the
backend uses camelCase (polluting the Python/Ruby codebase).
Consider a user record returned from a Python/Django REST API and consumed in TypeScript:
// What the Python backend serializes:
{
"first_name": "Ada",
"last_name": "Lovelace",
"created_at": "2026-04-04T12:00:00Z"
}
// What the TypeScript frontend ideally works with:
{
firstName: "Ada",
lastName: "Lovelace",
createdAt: "2026-04-04T12:00:00Z"
} The correct solution is a transform layer that converts keys at the
boundary. Libraries like humps (JavaScript) do this automatically:
import humps from 'humps';
const response = await fetch('/api/users/1');
const raw = await response.json();
const user = humps.camelizeKeys(raw);
// user.firstName === "Ada" ✓ On the backend side, Django REST Framework's CamelCaseJSONParser and similar
middleware handle the reverse transform. The key insight: each layer uses its own idiomatic convention, and the transform is an
explicit, tested boundary — not an ad-hoc fix sprinkled through the codebase.
How to Enforce Naming Conventions
The best naming convention is one enforced automatically, so developers don't have to think about it during code review. Here are the tools by ecosystem:
- JavaScript / TypeScript: ESLint with the
@typescript-eslint/naming-conventionrule. Configure it once in.eslintrcoreslint.config.jsand it will flag violations on every file save. - Python: Flake8 with the
pep8-namingplugin, or Ruff (faster, covers both linting and formatting). Both enforce PEP 8 naming out of the box. - Rust: The compiler itself warns on non-idiomatic names.
rustfmthandles formatting. No additional configuration needed for basic enforcement. - Go:
golint/staticcheckenforce naming and exported identifier comments. The compiler enforces the export visibility rule. - CSS: Stylelint with
stylelint-selector-bem-patternor a custom regex rule enforces kebab-case class names. - All languages: A written team style guide (even a short one) in the
repo's README or CONTRIBUTING.md eliminates ambiguity for cases that automated tools
miss (e.g., abbreviations like
URLvsUrlvsurl).
Running these tools as part of your CI pipeline — not just as optional editor plugins — ensures that naming violations never make it into the main branch, regardless of editor setup or developer preference.
Quick Reference: When to Use Which
| Style | Use for | Avoid for |
|---|---|---|
camelCase | JS/TS variables, functions, object keys; Go unexported identifiers; Java/C# variables | Python, Ruby, Rust functions; CSS class names; SQL columns |
PascalCase | Classes, types, interfaces, components across almost every language; Go exported identifiers | Variables, functions, CSS; anything that isn't a type or component |
snake_case | Python, Ruby, Rust variables/functions; SQL columns; database table names | JavaScript variables; CSS class names; Go identifiers |
kebab-case | CSS class names; HTML attributes; URL slugs; npm package names | Any programming language identifier (invalid syntax in most languages) |
SCREAMING_SNAKE_CASE | Constants and environment variables in almost every language | Variables that change; functions; types |
The pattern is consistent: follow what the language's own standard library does. Read the source of the standard library or framework you're building on top of. If NumPy
uses snake_case, your data science code should too. If React uses PascalCase for components, so should yours.
When you need to convert between styles — renaming a batch of variables, transforming API keys, or exploring what a string looks like in different conventions — a dedicated tool saves time. The Word Case Swap utility on this site converts any text instantly between camelCase, PascalCase, snake_case, kebab-case, and SCREAMING_SNAKE_CASE, with no installation required.