TL;DR: There are four main naming conventions in programming: camelCase (JavaScript), snake_case (Python), PascalCase (C#), and kebab-case (CSS/URLs). To convert between them, split the name into words, then rejoin using the target convention's rules. Follow whatever your language uses -- don't be the person writing snake_case in JavaScript.
If you have ever had to connect a Python API (which speaks snake_case) to a JavaScript frontend (which speaks camelCase) while mapping the data into a C# model (which insists on PascalCase), you have felt the pain. It is like being a translator at the United Nations, except everyone is arguing about underscores.
Let's break down the four major naming conventions, why they exist, and how to convert between them without losing your mind.
Meet the Four Naming Conventions
camelCase
First word lowercase, every word after that starts with a capital letter. No separators. Think of a camel's humps -- the uppercase letters are the humps.
firstName
getUserProfile
isAuthenticated
maxRetryCount
Who uses it: JavaScript, Java, TypeScript, Swift, Dart. If you write frontend code, this is your daily bread.
PascalCase (a.k.a. UpperCamelCase)
Same as camelCase, but the first word is capitalized too. It is like camelCase dressed up for a job interview.
FirstName
UserProfile
HttpResponse
DatabaseConnection
Who uses it: C# (for almost everything public), Java (class names), TypeScript (interfaces), React (component names).
snake_case
All lowercase, words separated by underscores. It slithers along the baseline like a... well, you get it.
first_name
get_user_profile
is_authenticated
max_retry_count
Who uses it: Python, Ruby, Rust, PHP (partially), PostgreSQL. Python's PEP 8 style guide mandates it for functions and variables.
kebab-case
All lowercase, words separated by hyphens. Named after a kebab skewer holding the words together. (Hungry yet?)
first-name
user-profile
is-authenticated
max-retry-count
Who uses it: CSS class names, HTML attributes, URL slugs, CLI arguments (like --dry-run). You cannot use kebab-case for variable names in most languages because the hyphen gets interpreted as a minus sign.
Why did the Python developer break up with the JavaScript developer? Because they had irreconcilable naming_differences. (camelCase just was not their_style.)
Why Do Different Languages Use Different Conventions?
These are not random choices. They evolved from each language's history and culture:
- JavaScript uses camelCase because it was designed in the mid-90s following Java conventions (Java was the cool kid at the time), and the DOM API itself uses camelCase (
getElementById,innerHTML). - Python uses snake_case because Guido van Rossum found it more readable. Fun fact: a 2010 study by Bonita Sharif and Jonathan Maletic found that programmers recognize snake_case identifiers about 20% faster than camelCase ones. Science backs the snake!
- CSS uses kebab-case because CSS properties have always been hyphenated (
background-color,font-size), so class names naturally followed suit.
How to Convert Between Conventions
Here is the key insight: every conversion is a two-step process. First, split the input into individual words. Then, rejoin them using the target convention. Once you understand this, it all clicks.
Step 1: Split Into Words
function splitIntoWords(str) {
return str
.replace(/([a-z])([A-Z])/g, '$1_$2') // camelCase boundaries
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') // acronym boundaries
.split(/[^a-zA-Z0-9]+/) // split on non-alphanumeric
.filter(word => word.length > 0)
.map(word => word.toLowerCase());
}
// "getUserProfile" -> ["get", "user", "profile"]
// "get_user_profile" -> ["get", "user", "profile"]
// "XMLHttpRequest" -> ["xml", "http", "request"]
The regex magic here inserts underscores at the boundaries between lowercase and uppercase letters, then splits on any non-letter-or-number character. The result is always a clean array of lowercase words, no matter what you feed it.
Step 2: Join in the Target Convention
function toCamelCase(words) {
return words[0] + words.slice(1)
.map(w => w[0].toUpperCase() + w.slice(1)).join('');
}
function toPascalCase(words) {
return words.map(w => w[0].toUpperCase() + w.slice(1)).join('');
}
function toSnakeCase(words) {
return words.join('_');
}
function toKebabCase(words) {
return words.join('-');
}
The Tricky Edge Cases
Real-world code is messier than textbook examples. Here are the gotchas:
Acronyms: "XMLHttpRequest" is the classic headache. Naive splitting gives you ["X", "M", "L", "Http", "Request"]. The robust regex above treats consecutive uppercase letters as a group, so you correctly get ["XML", "Http", "Request"] which becomes xml_http_request.
Numbers: Identifiers like "h2Database" or "utf8Encode" contain numbers. Your splitter should keep digits attached to adjacent letters: h2_database, utf8_encode.
Single letters: Converting "getX" to snake_case should give you "get_x", not "getx". Make sure your regex catches solo uppercase letters too.
Real-World Scenario: API Boundary Conversion
The most common place you will need this is at the boundary between a backend and frontend. Your Python API sends user_name, but your React app wants userName. Here is a handy recursive key transformer:
function transformKeys(obj, transformFn) {
if (Array.isArray(obj)) {
return obj.map(item => transformKeys(item, transformFn));
}
if (obj !== null && typeof obj === 'object') {
return Object.fromEntries(
Object.entries(obj).map(([key, value]) => [
transformFn(key),
transformKeys(value, transformFn)
])
);
}
return obj;
}
// Usage
const apiResponse = { user_name: "alice", created_at: "2026-01-01" };
const jsObject = transformKeys(apiResponse, key => {
const words = splitIntoWords(key);
return toCamelCase(words);
});
// Result: { userName: "alice", createdAt: "2026-01-01" }
Pro tip: Do the conversion at the API boundary -- once when data comes in, once when it goes out. Never mix naming styles within your codebase. Your future self (and your teammates) will thank you.
Best Practices
- Follow your language's convention. Do not use snake_case in JavaScript or camelCase in Python. Your code should feel native to its ecosystem.
- Be consistent within a project. If your language does not have a strong convention (looking at you, PHP), pick one and stick with it.
- Convert at the boundary. When data crosses between systems, convert at the integration point rather than mixing styles throughout.
- Let your linter enforce it. ESLint has
camelcase, Pylint hasnaming-style, RuboCop hasNaming/MethodName. Let the machines catch what humans miss.
Try It Yourself
Paste any identifier or block of text into our Case Converter tool to instantly convert between camelCase, PascalCase, snake_case, kebab-case, UPPER_CASE, and more. Works entirely in your browser.
Open Case Converter →