Case Conventions in Programming — camelCase, snake_case, kebab-case, PascalCase
Every programming language has opinions about how you name things. Variables, functions, classes, constants, file names, URL paths, database columns — each slot has a convention, and that convention usually maps to a specific case style. Violating the convention does not break your code. Your program will still compile and run. But it will confuse every other person who reads it, including future you.
The conventions exist for two reasons. First, readability: a consistent naming pattern lets you identify what something is at a glance. If you see MAX_RETRIESin a Python file, you know it is a constant before reading any surrounding code. Second, tooling: linters, formatters, and code generators expect certain patterns. ESLint’s naming-convention rule, Pylint’s snake_case enforcement, and RuboCop’s style checks all assume standard casing. Fight the convention and you fight your tools.
camelCase
Words are joined with no separator. The first word starts lowercase, every subsequent word is capitalized: firstName, getUserById, isReady.
camelCase is the default for variables and functions in JavaScript, TypeScript, Java, C#, Swift, and Kotlin. It is also the standard for JSON keys in most API style guides (Google, Stripe, GitHub). The reasoning is compact names that remain readable: the uppercase letters serve as visual separators without adding characters.
// JavaScript / TypeScript
const userName = 'alice';
function calculateTotalPrice(items) {
let runningTotal = 0;
// ...
}
// Java
int maxRetryCount = 3;
String formatDate(LocalDate date) { ... }One quirk: consecutive acronyms. Should it be xmlHttpRequest or XMLHTTPRequest or XmlHttpRequest? The JavaScript standard library uses XMLHttpRequest, mixing uppercase acronyms with camelCase. Google’s Java style guide says to treat acronyms as words: xmlHttpRequest. Most modern codebases follow the “treat acronyms as words” convention because it avoids ambiguity at boundaries — parseDBXml is harder to parse visually than parseDbXml.
PascalCase
Same as camelCase, but the first word is also capitalized: UserProfile, HttpClient, EventEmitter. Sometimes called UpperCamelCase.
PascalCase is reserved for types: classes in Java, C#, Python, and TypeScript; interfaces in C# and Go; React components in JSX; type aliases and enums in TypeScript. This distinction from camelCase is load-bearing. When you see Button in a JSX file, you know it is a component. When you see button, you know it is an HTML element. The casing carries semantic information.
// TypeScript / React
interface UserProfile {
displayName: string;
emailAddress: string;
}
function ProfileCard({ user }: { user: UserProfile }) {
return <div>{user.displayName}</div>;
}
// C#
class HttpClient { ... }
enum LogLevel { Debug, Info, Warning, Error }snake_case
Words are lowercase, separated by underscores: user_name, get_user_by_id, is_ready.
snake_case dominates in Python, Ruby, Rust, Elixir, and SQL. It is also the standard for C standard library functions (strncpy, fopen— though old C often drops the underscores entirely) and for PostgreSQL column names. The Python community is especially strict about this. PEP 8 specifies snake_case for functions, methods, variables, and module names. Writing getUserById in Python works, but every Python developer who reads it will flinch.
# Python
user_name = 'alice'
def calculate_total_price(items):
running_total = 0
# ...
# Ruby
def format_date(date)
date.strftime('%Y-%m-%d')
end
# SQL
SELECT first_name, last_name
FROM user_accounts
WHERE created_at > '2026-01-01';snake_case is arguably the most readable style for long names. get_user_profile_by_email_address is immediately parseable, while getUserProfileByEmailAddressrequires your eye to find the uppercase transitions. The tradeoff is length — underscores add characters.
kebab-case
Words are lowercase, separated by hyphens: user-name, primary-button, max-width. Also called hyphen-case, dash-case, or lisp-case (Lisp dialects have used hyphens in identifiers since the 1950s).
kebab-case is standard in CSS property names and class names, HTML attributes (data-user-id), URLs and URL slugs, CLI flags (--output-dir), and YAML/TOML config keys. You cannot use kebab-case for variable names in most programming languages because the hyphen is the subtraction operator — user-name would be parsed as user minus name. This restricts kebab-case to contexts where hyphens are not ambiguous: strings, file names, markup attributes, and configuration.
/* CSS */
.primary-button {
background-color: var(--accent-color);
border-radius: 8px;
font-weight: 600;
}
<!-- HTML -->
<div data-user-id="42" class="card-header">...</div>
# CLI
npx create-next-app --src-dir --import-alias "@/*"File naming in frontend projects often uses kebab-case: user-profile.tsx, api-client.ts, use-auth.ts. This avoids case-sensitivity issues across operating systems. macOS treats UserProfile.tsx and userprofile.tsx as the same file; Linux does not. A kebab-case file name sidesteps the problem entirely.
CONSTANT_CASE
All uppercase letters, words separated by underscores: MAX_RETRIES, API_BASE_URL, DEFAULT_TIMEOUT_MS. Also called SCREAMING_SNAKE_CASE or UPPER_SNAKE_CASE.
CONSTANT_CASE signals immutability. The value is set once and never changes at runtime. It appears in every mainstream language for constants, enum values, and environment variables. In Java, it applies to static finalfields. In Python, it is a convention only — Python has no true constants, but PEP 8 says to name module-level constants in UPPER_CASE. In JavaScript, it marks values declared with const that are genuinely fixed (not every const variable — a const object reference can still have its properties mutated).
// JavaScript
const MAX_RETRIES = 3;
const API_BASE_URL = 'https://api.example.com/v2';
# Python
DEFAULT_TIMEOUT_MS = 5000
DATABASE_URL = os.environ['DATABASE_URL']
// Java
public static final int MAX_CONNECTIONS = 100;The Mixed-Codebase Problem
Real projects rarely live in a single language. A typical web application has a Python or Ruby backend serving a JSON API consumed by a JavaScript frontend, with SQL underneath and CSS on top. Each layer has its own convention:
# Python backend (snake_case)
user_profile = { "first_name": "Alice", "last_name": "Chen" }
// JavaScript frontend (camelCase)
const userProfile = { firstName: 'Alice', lastName: 'Chen' };
/* CSS (kebab-case) */
.user-profile-card { ... }
-- SQL (snake_case)
SELECT first_name FROM user_profiles;The friction point is the API boundary. Your Python backend returns first_name. Your JavaScript frontend expects firstName. Something has to convert between the two.
There are three common approaches. First, the backend serializes to camelCase for JSON responses, converting at the API layer. Django REST Framework has CamelCaseJSONRenderer for exactly this. Second, the frontend converts incoming snake_case keys to camelCase on receipt, using a utility like camelcase-keysor a custom transformer in the HTTP client. Third, both sides agree on one convention for the wire format — usually camelCase, since JSON originated in JavaScript. The third option is cleanest but requires the backend to violate its own language conventions at the serialization layer.
Whichever approach you pick, be consistent. The worst outcome is a codebase where some API fields arrive as user_name and others as userName because different endpoints were written by different people at different times with no agreed-upon convention.
Linters and Automated Enforcement
Convention arguments become moot when a linter enforces the rule. Most languages have a standard tool:
JavaScript/TypeScript: ESLint’s @typescript-eslint/naming-convention rule lets you specify required formats for variables, functions, classes, interfaces, type aliases, and enum members individually. You can require camelCase for variables, PascalCase for types, and UPPER_CASE for enum members in a single rule configuration.
Python: Pylint checks naming conventions by default. PEP 8 compliance tools like flake8 with the pep8-naming plugin catch camelCase function names and flag them. The ruff linter (now the fastest Python linter) includes these checks with zero configuration.
Rust: The compiler itself warns about non-standard naming. Defining a function as fn GetUser() triggers a non_snake_case warning by default. Rust is one of the few languages where the naming convention is enforced at the compiler level, not by an external tool.
CSS: Stylelint’s selector-class-pattern rule enforces class name formats. BEM methodology uses a specific pattern (block__element--modifier) that Stylelint can validate.
Picking the Right Convention
The rules are simpler than they seem. Follow whatever your language community uses. If you are writing Python, use snake_case. If you are writing JavaScript, use camelCase for variables and PascalCase for components and types. If you are naming a CSS class, use kebab-case. If you have a constant that never changes, use CONSTANT_CASE.
When you need to convert between styles — transforming an API response, reformatting a database column name for display, or just checking what getUserProfilelooks like in snake_case — a case converter handles it instantly. Type or paste your text, and every case style appears at once.
The naming convention is not the interesting part of your codebase. Pick one, enforce it with a linter, and spend your mental energy on the actual problem you are solving.
Try it yourself
Use our free Case Converter — runs entirely in your browser, no sign-up required.