Introduction: Naming Is Communication
Code is read far more often than it is written. Estimates vary, but a widely cited figure from Robert C. Martin's Clean Code puts the ratio at roughly 10:1 — for every line of code you write, ten developers will read it over the lifetime of the project. This means that the names you choose for variables, functions, classes, and files are not just labels for the compiler; they are messages to every future reader, including yourself six months from now.
Naming conventions — the rules governing which case format to use and when — are one of the most impactful decisions a team can make. Consistent naming reduces cognitive load, makes code searchable, prevents bugs caused by case sensitivity, and signals professionalism in open-source projects. Inconsistent naming, on the other hand, forces readers to constantly switch mental models: "Is this a class or a variable? A constant or a function? A private member or a public API?"
This guide walks through the major naming conventions, explains which languages use which format, addresses the friction that occurs at system boundaries, and offers practical advice for enforcement.
The Big Four: camelCase, PascalCase, snake_case, kebab-case
Almost all naming conventions in modern programming are built on four core formats. Learning to recognize them at a glance is a fundamental developer skill:
- camelCase — words are joined with no separator; every word after the first is capitalized:
getUserProfile,isEnabled,totalItemCount. The lowercase first letter immediately tells you this is a variable or function, not a type. - PascalCase — identical to camelCase but the first letter is also uppercase:
UserProfile,HttpClient,DatabaseConnection. The uppercase first letter universally signals a class, interface, type, or constructor. - snake_case — all lowercase with underscores between words:
get_user_profile,is_enabled,total_item_count. The underscores create visual word boundaries similar to natural language, which many developers find more readable than camelCase. - kebab-case — all lowercase with hyphens between words:
get-user-profile,is-enabled,primary-button. Cannot be used as an identifier in most languages (the hyphen is a minus operator) but is the standard for CSS, HTML attributes, URLs, and CLI arguments.
A fifth format, CONSTANT_CASE (all uppercase with underscores: MAX_RETRIES, API_BASE_URL), is universally used for constants across nearly all languages.
Language Conventions: Who Uses What
Each programming language community has settled on specific conventions, often codified in an official style guide. Violating these conventions makes your code look foreign to other developers in that ecosystem:
JavaScript / TypeScript
Variables and functions use camelCase: const userName = getUser(). Classes and React components use PascalCase: class UserProfile, <NavBar />. Constants use CONSTANT_CASE: const MAX_RETRIES = 3. File names for components use PascalCase (UserProfile.tsx) or kebab-case (user-profile.tsx) depending on the project. TypeScript interfaces and types use PascalCase: interface UserData. Enum members use PascalCase or CONSTANT_CASE depending on the team.
Python
PEP 8 mandates snake_case for variables, functions, and methods: def get_user_profile(). Classes use PascalCase: class UserProfile. Constants use CONSTANT_CASE: MAX_RETRIES = 3. Private members are prefixed with an underscore: _internal_cache. Name-mangled members use double underscores: __secret. Modules and packages use short snake_case names.
Java
Variables and methods use camelCase: getUserProfile(). Classes and interfaces use PascalCase: class UserProfile implements Serializable. Constants use CONSTANT_CASE: static final int MAX_RETRIES = 3. Packages use all lowercase with dots: com.example.userprofile.
CSS
Properties are defined by the specification in kebab-case: background-color, font-size. Class names follow the same pattern: .primary-button, .nav-bar. The BEM methodology extends this with double underscores and double hyphens: .card__header--highlighted.
Go
Go uses case as an access control mechanism. PascalCase identifiers are exported (public): func GetUser(). camelCase identifiers are unexported (private): func getUser(). This is enforced by the compiler, not just convention. Acronyms stay fully capitalized: HTTPClient, XMLParser, ID.
Rust
Variables and functions use snake_case: fn get_user_profile(). Types, traits, and enums use PascalCase: struct UserProfile. Constants use CONSTANT_CASE: const MAX_RETRIES: u32 = 3. The Rust compiler issues warnings for naming convention violations, making it one of the most strictly enforced languages.
Ruby
Variables and methods use snake_case: get_user_profile. Classes and modules use PascalCase: class UserProfile. Constants use CONSTANT_CASE or PascalCase: MAX_RETRIES = 3. Predicate methods end with a question mark: enabled?. Destructive methods end with an exclamation mark: save!.
When Conventions Collide: API Boundaries
The hardest naming problems arise where two systems with different conventions meet. These boundaries are a constant source of confusion and bugs:
JSON APIs: camelCase vs snake_case
A JavaScript frontend sends {"userName": "alice"} (camelCase) to a Python backend that expects {"user_name": "alice"} (snake_case). Both teams are following their language's conventions, but the data must be transformed at the boundary. Common solutions include serialization libraries that handle conversion automatically, or agreeing on one format for the API contract (camelCase is more common in REST APIs because JSON is a JavaScript notation).
Database Columns
SQL traditionally uses snake_case for column names (user_name, created_at), but ORMs map these to camelCase or PascalCase in application code. Django auto-converts to Python snake_case. Sequelize can be configured with underscored: true. JPA uses @Column(name = "user_name") annotations. The key principle: let each layer use its own convention and convert at the boundary.
CSS-in-JS
CSS properties are kebab-case (background-color), but in JavaScript objects they must be camelCase (backgroundColor) because hyphens are not valid in JS identifiers. Every CSS-in-JS library (styled-components, Emotion, Tailwind utilities) handles this automatically, but developers writing inline styles must remember the conversion.
Automatic Case Conversion in Serialization
Most modern frameworks provide built-in mechanisms to convert between naming conventions at serialization boundaries:
- Jackson (Java):
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)converts PascalCase or camelCase fields to snake_case in JSON output. - Pydantic (Python):
model_config = ConfigDict(alias_generator=to_camel)generates camelCase aliases for snake_case fields, so the API speaks camelCase while Python code stays Pythonic. - Sequelize (Node.js):
underscored: truein model options maps camelCase attributes to snake_case database columns. - Gson (Java):
FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORESserializes camelCase fields as snake_case. - System.Text.Json (.NET):
JsonNamingPolicy.SnakeCaseLowerconverts PascalCase properties to snake_case.
These solutions ensure that each layer of the stack uses its native naming convention while data flows seamlessly between them.
Linting and Enforcement
Conventions are only useful when enforced. Without automated checks, naming drift is inevitable as teams grow. Every major language has linting tools that catch naming violations:
- ESLint (JavaScript/TypeScript): The
camelcaserule enforces camelCase for variables. The@typescript-eslint/naming-conventionrule allows fine-grained control — different rules for variables, functions, classes, interfaces, and type parameters. - pylint / flake8 (Python): The
naming-conventionchecker validates PEP 8 compliance for all identifier types.flake8-namingis a popular plugin that catches issues like class names in snake_case or constants in camelCase. - RuboCop (Ruby): The
Namingdepartment enforces Ruby community conventions with rules for method names, variable names, class names, and constant names. - clippy (Rust): Built into the Rust toolchain, clippy warns on naming convention violations by default. The compiler itself warns if you define a function in PascalCase or a struct in snake_case.
- golint / staticcheck (Go): Checks for exported name conventions and warns if acronyms are not fully capitalized.
The best practice is to add naming rules to your CI pipeline so violations are caught before code review. This removes the burden from human reviewers and eliminates subjective style discussions.
Refactoring Case: Renaming at Scale
When you need to change a naming convention across a codebase — perhaps migrating from Hungarian notation to camelCase, or aligning API fields after a team merger — the approach matters more than the tool:
- IDE rename refactoring (F2 in VS Code, Shift+F6 in IntelliJ) is the safest approach for individual identifiers. It understands scope and updates all references, including imports, type annotations, and string references in some cases.
- grep/sed for bulk changes is tempting but dangerous. A naïve
sed 's/user_name/userName/g'will also transform string literals, comments, column names, and URL fragments. Always review diffs carefully. - AST-based codemods (jscodeshift for JavaScript, libcst for Python) understand the syntax tree and only rename actual identifiers, not string contents. This is the safest approach for large-scale renaming.
- Case conversion tools like our case converter are useful for converting lists of names extracted from a codebase — paste variable names, convert to the target format, and use the results in your refactoring script.
A common strategy is to introduce the new convention gradually: new code follows the new convention, and legacy code is migrated file by file alongside feature work, rather than in one risky big-bang refactor.
Team Conventions: Documenting and Onboarding
For naming conventions to stick in a team, they must be documented, automated, and part of the onboarding process:
- Document in CONTRIBUTING.md or a dedicated STYLE_GUIDE.md. List the naming convention for each construct (variables, functions, classes, constants, files, database columns, API fields) with examples.
- Enforce in CI with linting rules. If the CI pipeline passes, the naming is correct — no ambiguity, no arguments in code reviews.
- Use editor config:
.editorconfigand language-specific config files (.eslintrc,pyproject.toml) ensure every developer's editor applies the same rules automatically. - Include in onboarding: New developers should learn the naming conventions on their first day. A well-structured codebase teaches by example, but explicit documentation prevents assumptions.
- Review and update: Conventions should evolve. If a rule causes friction (e.g., fully capitalizing long acronyms like
XMLHTTPRequest), discuss it as a team and update the guide.
Special Cases and Edge Cases
Acronyms: XMLParser vs XmlParser
This is one of the most debated naming questions. Google's Java style guide treats acronyms as words: XmlParser, HttpClient, JsonUtil. Microsoft's C# guide preserves two-letter acronyms but lowercases longer ones: IOStream but HtmlParser. Go capitalizes all acronyms: HTTPClient, XMLParser, ID. The best advice: pick one rule, document it, and enforce it. Consistency matters more than which rule you choose.
Single-Letter Variables
Single-letter names like i, j, k for loop counters and x, y for coordinates are widely accepted by convention. Other common single-letter names include e for events or exceptions, t for time, and n for count. Beyond these established conventions, prefer descriptive names: userIndex over u.
Hungarian Notation (Legacy)
Prefixing variable names with a type abbreviation (strName, intCount, bIsEnabled) was common in C and early Windows programming. It is now considered an antipattern in most languages because modern editors show type information on hover, and the prefixes add noise without value. You may still encounter it in legacy codebases and some C/C++ projects following Microsoft conventions.
Private Members: Prefix Conventions
Some conventions mark private members with prefixes: underscore in Python (_cache), underscore in C++ (_member or m_member), hash in JavaScript (#privateField). These are language-specific conventions — do not transfer them across languages (e.g., do not use underscore prefixes in Java, which has explicit access modifiers).
Our Case Converter for Quick Conversions
When you are working across language boundaries, refactoring code, or cleaning up data, the case converter tool can save significant time. Paste a list of variable names in any format, and convert them all to your target convention instantly. The tool supports 17 formats including all the conventions discussed in this article: camelCase, PascalCase, snake_case, kebab-case, CONSTANT_CASE, dot.case, and path/case.
For batch operations, the tool's file upload feature handles .txt, .csv, and .json files directly. CSV headers can be converted independently of cell data, and JSON keys are recursively converted while preserving values. The multi-line mode lets you apply different case formats to individual lines — useful when a file contains a mix of identifiers that need different treatments.
Everything runs in your browser with zero server communication, making it safe for proprietary code and confidential data. Convert, review the diff, and download the result — all without leaving your browser.