The conventions
- camelCase:
userAccountBalance— first word lowercase, subsequent words capitalized. The humps give it the name. - PascalCase:
UserAccountBalance— every word capitalized. Used for classes and types. - snake_case:
user_account_balance— lowercase words joined by underscores. - kebab-case:
user-account-balance— lowercase words joined by hyphens. - SCREAMING_SNAKE_CASE:
MAX_RETRIES— constants, by near-universal agreement.
What each language expects
- JavaScript/TypeScript: camelCase for variables and functions, PascalCase for classes and components.
- Python: snake_case for variables and functions, PascalCase for classes (per PEP 8).
- Java/C#: camelCase for variables/methods, PascalCase for classes.
- URLs and file names: kebab-case —
/blog/camelcase-vs-snakecase. Underscores in URLs are technically fine but hyphens are the convention and read better. - CSS: kebab-case for classes and properties (
background-color). - Databases: snake_case for tables and columns in most traditions.
- Environment variables: SCREAMING_SNAKE_CASE (
DATABASE_URL).
When crossing boundaries (JS frontend talking to a Python API), convert at the boundary — many frameworks do this automatically — rather than mixing conventions in one codebase.
Does it actually matter?
More than it looks. Studies on identifier readability find snake_case slightly faster to read accurately than camelCase, but the dominant factor is consistency: a codebase mixing userName, user_name, and user-name forces readers to re-derive meaning constantly. Linters (ESLint, Ruff, RuboCop) can enforce your chosen convention automatically — turn those rules on.
Practical rules
- Follow the language's convention — it is what every reader of that language expects.
- Be consistent within a project. Document the choice in the README or contributing guide.
- Use SCREAMING_SNAKE_CASE for constants everywhere.
- Convert, do not hand-retype. Paste identifiers into our case converter to switch between camelCase, snake_case, kebab-case, and PascalCase instantly and error-free.
Beyond case: naming things well
Case conventions are formatting; naming is the actual hard problem. A consistently-cased bad name (user_data_final_v2) is still a bad name. Principles that outrank casing debates:
- Names should reveal intent.
daysUntilExpirybeatsdortmp2. The reader should not need surrounding code to understand a variable. - Avoid mental mapping. If you must keep a comment explaining what a name means, the name failed. Ditto single-letter variables outside tiny loop scopes.
- Banish noise words.
data,info,manager,handleradd syllables, not meaning.accountList→accounts. - One word per concept. Do not call the same thing
user,account, andmemberin different files. Pick one; enforce it in review. - Pronounceable names win. If you cannot say it in a standup without spelling it, rename it.
Get the words right first, then apply the casing convention mechanically — our case converter handles the mechanical part in one click.
Enforce all of this with linters, not willpower. ESLint's naming-convention rule, Ruff's pep8-naming, and similar checks catch violations at commit time, before they fossilize into the codebase. Add naming to your code-review checklist too: reviewers should feel empowered to say "this name confused me" — confusion in review predicts confusion in production debugging at 2 AM. Teams that treat naming as a reviewable quality ship codebases that stay readable as they grow — and onboarding new developers becomes dramatically easier when every name already explains itself without requiring a tour guide through the codebase. Good names compound: each clear identifier makes the next one easier to choose well.
Naming is one of the two hard problems in computer science — conventions do not solve it, but they remove one axis of confusion. For prose capitalization, see title case rules and sentence vs. title case.